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

Unified Diff: chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelEventFilterTest.java

Issue 1808653006: Add tests for the OverlayPanelEventFilter (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@overlaypaneleventfilter
Patch Set: fix findbugs Created 4 years, 7 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
« no previous file with comments | « chrome/android/java_sources.gni ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelEventFilterTest.java
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelEventFilterTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelEventFilterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..f560b5f0a276470828e7da10cae8bd660c161ee5
--- /dev/null
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/bottombar/OverlayPanelEventFilterTest.java
@@ -0,0 +1,492 @@
+// Copyright 2016 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.
+
+package org.chromium.chrome.browser.compositor.bottombar;
+
+import android.content.Context;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+
+import org.chromium.base.test.util.Feature;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.EventFilterHost;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.OverlayPanelEventFilter;
+import org.chromium.content.browser.ContentViewCore;
+
+/**
+ * Class responsible for testing the OverlayPanelEventFilter.
+ */
+public class OverlayPanelEventFilterTest extends InstrumentationTestCase {
+
+ private static final float PANEL_ALMOST_MAXIMIZED_OFFSET_Y_DP = 50.f;
+ private static final float BAR_HEIGHT_DP = 100.f;
+
+ private static final float LAYOUT_WIDTH_DP = 600.f;
+ private static final float LAYOUT_HEIGHT_DP = 800.f;
+
+ // A small value used to check whether two floats are almost equal.
+ private static final float EPSILON = 1e-04f;
+
+ private float mTouchSlopDp;
+ private float mDpToPx;
+
+ private float mAlmostMaximizedContentOffsetYDp;
+ private float mMaximizedContentOffsetYDp;
+
+ private float mContentVerticalScroll;
+
+ private boolean mWasTapDetectedOnContent;
+ private boolean mWasScrollDetectedOnContent;
+
+ private MockOverlayPanel mPanel;
+ private OverlayPanelEventFilterWrapper mEventFilter;
+
+ private boolean mShouldLockHorizontalMotionInContent;
+ private MotionEvent mEventPropagatedToContent;
+ private boolean mEventWasScroll;
+ private boolean mEventWasTap;
+
+ // --------------------------------------------------------------------------------------------
+ // OverlayPanelEventFilterWrapper
+ // --------------------------------------------------------------------------------------------
+
+ /**
+ * Wrapper around OverlayPanelEventFilter used by tests.
+ */
+ public final class OverlayPanelEventFilterWrapper extends OverlayPanelEventFilter {
+ public OverlayPanelEventFilterWrapper(Context context, EventFilterHost host,
+ OverlayPanel panel) {
+ super(context, host, panel);
+ }
+
+ @Override
+ protected float getContentViewVerticalScroll() {
+ return mContentVerticalScroll;
+ }
+
+ @Override
+ protected void propagateEventToContentViewCore(MotionEvent e) {
+ mEventPropagatedToContent = MotionEvent.obtain(e);
+ super.propagateEventToContentViewCore(e);
+ mEventPropagatedToContent.recycle();
+ }
+
+ @Override
+ protected boolean handleSingleTapUp(MotionEvent e) {
+ boolean handled = super.handleSingleTapUp(e);
+ mEventWasTap = true;
+ return handled;
+ }
+
+ @Override
+ protected boolean handleScroll(MotionEvent e1, MotionEvent e2, float distanceY) {
+ boolean handled = super.handleScroll(e1, e2, distanceY);
+ mEventWasScroll = true;
+ return handled;
+ }
+ }
+
+ // --------------------------------------------------------------------------------------------
+ // StubbedContentViewCore
+ // --------------------------------------------------------------------------------------------
+
+ private final class StubbedContentViewCore extends ContentViewCore {
+ public StubbedContentViewCore(Context context) {
+ super(context);
+ }
+
+ @Override
+ public ViewGroup getContainerView() {
+ return new ViewGroup(getContext()) {
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent e) {
+ if (e.getActionMasked() != MotionEvent.ACTION_CANCEL) {
+ mWasScrollDetectedOnContent = mEventWasScroll;
+ mWasTapDetectedOnContent = mEventWasTap;
+
+ // Check that the event offset is correct.
+ if (!mShouldLockHorizontalMotionInContent) {
+ float propagatedEventY = mEventPropagatedToContent.getY();
+ float offsetY = mPanel.getContentY() * mDpToPx;
+ assertEquals(propagatedEventY - offsetY, e.getY(), EPSILON);
+ }
+ } else {
+ mWasScrollDetectedOnContent = false;
+ mWasTapDetectedOnContent = false;
+ }
+ return super.dispatchTouchEvent(e);
+ }
+
+ @Override
+ public void onLayout(boolean changed, int l, int t, int r, int b) {}
+ };
+ }
+ }
+
+ // --------------------------------------------------------------------------------------------
+ // MockOverlayPanel
+ // --------------------------------------------------------------------------------------------
+
+ /**
+ * Mocks an OverlayPanel, so it doesn't create ContentViewCore.
+ */
+ public final class MockOverlayPanel extends OverlayPanel {
+ private boolean mWasTapDetectedOnPanel = false;
+ private boolean mWasScrollDetectedOnPanel = false;
+ private ContentViewCore mContentViewCore;
+
+ public MockOverlayPanel(Context context, OverlayPanelManager panelManager) {
+ super(context, null, null, panelManager);
+ mContentViewCore = new StubbedContentViewCore(context);
+ }
+
+ @Override
+ public OverlayPanelContent createNewOverlayPanelContent() {
+ return new MockOverlayPanelContent();
+ }
+
+ /**
+ * Override creation and destruction of the ContentViewCore as they rely on native methods.
+ */
+ private class MockOverlayPanelContent extends OverlayPanelContent {
+ public MockOverlayPanelContent() {
+ super(null, null, null);
+ }
+
+ @Override
+ public void removeLastHistoryEntry(String url, long timeInMs) {}
+ }
+
+ @Override
+ public ContentViewCore getContentViewCore() {
+ return mContentViewCore;
+ }
+
+ public boolean getWasTapDetected() {
+ return mWasTapDetectedOnPanel;
+ }
+
+ public boolean getWasScrollDetected() {
+ return mWasScrollDetectedOnPanel;
+ }
+
+ // GestureHandler overrides.
+
+ @Override
+ public void onDown(float x, float y, boolean fromMouse, int buttons) {}
+
+ @Override
+ public void onUpOrCancel() {}
+
+ @Override
+ public void drag(float x, float y, float dx, float dy, float tx, float ty) {
+ mWasScrollDetectedOnPanel = true;
+ }
+
+ @Override
+ public void click(float x, float y, boolean fromMouse, int buttons) {
+ mWasTapDetectedOnPanel = true;
+ }
+
+ @Override
+ public void fling(float x, float y, float velocityX, float velocityY) {}
+
+ @Override
+ public void onLongPress(float x, float y) {}
+
+ @Override
+ public void onPinch(float x0, float y0, float x1, float y1, boolean firstEvent) {}
+ }
+
+ // --------------------------------------------------------------------------------------------
+ // Test Suite
+ // --------------------------------------------------------------------------------------------
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ Context context = getInstrumentation().getTargetContext();
+
+ mDpToPx = context.getResources().getDisplayMetrics().density;
+ mTouchSlopDp = ViewConfiguration.get(context).getScaledTouchSlop() / mDpToPx;
+
+ mPanel = new MockOverlayPanel(context, new OverlayPanelManager());
+ mEventFilter = new OverlayPanelEventFilterWrapper(context, null, mPanel);
+
+ mPanel.setSearchBarHeightForTesting(BAR_HEIGHT_DP);
+ mPanel.setHeightForTesting(LAYOUT_HEIGHT_DP);
+ mPanel.setIsFullWidthSizePanelForTesting(true);
+
+ // NOTE(pedrosimonetti): This should be called after calling the method
+ // setIsFullWidthSizePanelForTesting(), otherwise it will crash the test.
+ mPanel.onSizeChanged(LAYOUT_WIDTH_DP, LAYOUT_HEIGHT_DP);
+
+ setContentViewVerticalScroll(0);
+
+ mAlmostMaximizedContentOffsetYDp =
+ PANEL_ALMOST_MAXIMIZED_OFFSET_Y_DP + BAR_HEIGHT_DP;
+ mMaximizedContentOffsetYDp = BAR_HEIGHT_DP;
+
+ mWasTapDetectedOnContent = false;
+ mWasScrollDetectedOnContent = false;
+
+ mShouldLockHorizontalMotionInContent = false;
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testTapContentView() {
+ positionPanelInAlmostMaximizedState();
+
+ // Simulate tap.
+ simulateActionDownEvent(0.f, mAlmostMaximizedContentOffsetYDp + 1.f);
+ simulateActionUpEvent(0.f, mAlmostMaximizedContentOffsetYDp + 1.f);
+
+ assertFalse(mPanel.getWasScrollDetected());
+ assertFalse(mPanel.getWasTapDetected());
+
+ assertTrue(mWasTapDetectedOnContent);
+ assertFalse(mWasScrollDetectedOnContent);
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testScrollingContentViewDragsPanel() {
+ positionPanelInAlmostMaximizedState();
+
+ // Simulate swipe up sequence.
+ simulateActionDownEvent(0.f, mAlmostMaximizedContentOffsetYDp + 1.f);
+ simulateActionMoveEvent(0.f, mMaximizedContentOffsetYDp);
+ simulateActionUpEvent(0.f, mMaximizedContentOffsetYDp);
+
+ assertTrue(mPanel.getWasScrollDetected());
+ assertFalse(mPanel.getWasTapDetected());
+
+ assertFalse(mWasScrollDetectedOnContent);
+ assertFalse(mWasTapDetectedOnContent);
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testScrollUpContentView() {
+ positionPanelInMaximizedState();
+
+ // Simulate swipe up sequence.
+ simulateActionDownEvent(0.f, mAlmostMaximizedContentOffsetYDp + 1.f);
+ simulateActionMoveEvent(0.f, mMaximizedContentOffsetYDp);
+ simulateActionUpEvent(0.f, mMaximizedContentOffsetYDp);
+
+ assertFalse(mPanel.getWasScrollDetected());
+ assertFalse(mPanel.getWasTapDetected());
+
+ assertTrue(mWasScrollDetectedOnContent);
+ assertFalse(mWasTapDetectedOnContent);
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testScrollDownContentView() {
+ positionPanelInMaximizedState();
+
+ // When the Panel is maximized and the scroll position is greater than zero, a swipe down
+ // on the ContentView should trigger a scroll on it.
+ setContentViewVerticalScroll(100.f);
+
+ // Simulate swipe down sequence.
+ simulateActionDownEvent(0.f, mMaximizedContentOffsetYDp + 1.f);
+ simulateActionMoveEvent(0.f, mAlmostMaximizedContentOffsetYDp);
+ simulateActionUpEvent(0.f, mAlmostMaximizedContentOffsetYDp);
+
+ assertFalse(mPanel.getWasScrollDetected());
+ assertFalse(mPanel.getWasTapDetected());
+
+ assertTrue(mWasScrollDetectedOnContent);
+ assertFalse(mWasTapDetectedOnContent);
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testDragByOverscrollingContentView() {
+ positionPanelInMaximizedState();
+
+ // When the Panel is maximized and the scroll position is zero, a swipe down on the
+ // ContentView should trigger a swipe on the Panel.
+ setContentViewVerticalScroll(0.f);
+
+ // Simulate swipe down sequence.
+ simulateActionDownEvent(0.f, mMaximizedContentOffsetYDp + 1.f);
+ simulateActionMoveEvent(0.f, mAlmostMaximizedContentOffsetYDp);
+ simulateActionUpEvent(0.f, mAlmostMaximizedContentOffsetYDp);
+
+ assertTrue(mPanel.getWasScrollDetected());
+ assertFalse(mPanel.getWasTapDetected());
+
+ assertFalse(mWasScrollDetectedOnContent);
+ assertFalse(mWasTapDetectedOnContent);
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testUnwantedScrollDoesNotHappenInContentView() {
+ positionPanelInAlmostMaximizedState();
+
+ float contentViewOffsetYStart = mAlmostMaximizedContentOffsetYDp + 1.f;
+ float contentViewOffsetYEnd = mMaximizedContentOffsetYDp - 1.f;
+
+ // Simulate swipe up to maximized position.
+ simulateActionDownEvent(0.f, contentViewOffsetYStart);
+ simulateActionMoveEvent(0.f, mMaximizedContentOffsetYDp);
+ positionPanelInMaximizedState();
+
+ // Confirm that the Panel got a scroll event.
+ assertTrue(mPanel.getWasScrollDetected());
+
+ // Continue the swipe up for one more dp. From now on, the events might be forwarded
+ // to the ContentView.
+ simulateActionMoveEvent(0.f, contentViewOffsetYEnd);
+ simulateActionUpEvent(0.f, contentViewOffsetYEnd);
+
+ // But 1 dp is not enough to trigger a scroll in the ContentView, and in this
+ // particular case, it should also not trigger a tap because the total displacement
+ // of the touch gesture is greater than the touch slop.
+ float contentViewOffsetDelta =
+ contentViewOffsetYStart - contentViewOffsetYEnd;
+ assertTrue(Math.abs(contentViewOffsetDelta) > mTouchSlopDp);
+
+ assertFalse(mPanel.getWasTapDetected());
+
+ assertFalse(mWasScrollDetectedOnContent);
+ assertFalse(mWasTapDetectedOnContent);
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testDragPanelThenContinuouslyScrollContentView() {
+ positionPanelInAlmostMaximizedState();
+
+ // Simulate swipe up to maximized position.
+ simulateActionDownEvent(0.f, mAlmostMaximizedContentOffsetYDp + 1.f);
+ simulateActionMoveEvent(0.f, mMaximizedContentOffsetYDp);
+ positionPanelInMaximizedState();
+
+ // Confirm that the Panel got a scroll event.
+ assertTrue(mPanel.getWasScrollDetected());
+
+ // Continue the swipe up for one more dp. From now on, the events might be forwarded
+ // to the ContentView.
+ simulateActionMoveEvent(0.f, mMaximizedContentOffsetYDp - 1.f);
+
+ // Now keep swiping up an amount greater than the touch slop. In this case a scroll
+ // should be triggered in the ContentView.
+ simulateActionMoveEvent(0.f, mMaximizedContentOffsetYDp - 2 * mTouchSlopDp);
+ simulateActionUpEvent(0.f, mMaximizedContentOffsetYDp - 2 * mTouchSlopDp);
+
+ assertFalse(mPanel.getWasTapDetected());
+
+ assertTrue(mWasScrollDetectedOnContent);
+ assertFalse(mWasTapDetectedOnContent);
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testTapPanel() {
+ positionPanelInAlmostMaximizedState();
+
+ // Simulate tap.
+ simulateActionDownEvent(0.f, mAlmostMaximizedContentOffsetYDp - 1.f);
+ simulateActionUpEvent(0.f, mAlmostMaximizedContentOffsetYDp - 1.f);
+
+ assertFalse(mPanel.getWasScrollDetected());
+ assertTrue(mPanel.getWasTapDetected());
+
+ assertFalse(mWasScrollDetectedOnContent);
+ assertFalse(mWasTapDetectedOnContent);
+ }
+
+ @SmallTest
+ @Feature({"OverlayPanel"})
+ public void testScrollPanel() {
+ positionPanelInAlmostMaximizedState();
+
+ // Simulate swipe up sequence.
+ simulateActionDownEvent(0.f, mAlmostMaximizedContentOffsetYDp - 1.f);
+ simulateActionMoveEvent(0.f, mMaximizedContentOffsetYDp);
+ simulateActionUpEvent(0.f, mMaximizedContentOffsetYDp);
+
+ assertTrue(mPanel.getWasScrollDetected());
+ assertFalse(mPanel.getWasTapDetected());
+
+ assertFalse(mWasScrollDetectedOnContent);
+ assertFalse(mWasTapDetectedOnContent);
+ }
+
+ // --------------------------------------------------------------------------------------------
+ // Helpers
+ // --------------------------------------------------------------------------------------------
+
+ /**
+ * Positions the Panel in the almost maximized state.
+ */
+ private void positionPanelInAlmostMaximizedState() {
+ mPanel.setMaximizedForTesting(false);
+ mPanel.setOffsetYForTesting(PANEL_ALMOST_MAXIMIZED_OFFSET_Y_DP);
+ }
+
+ /**
+ * Positions the Panel in the maximized state.
+ */
+ private void positionPanelInMaximizedState() {
+ mPanel.setMaximizedForTesting(true);
+ mPanel.setOffsetYForTesting(0);
+ }
+
+ /**
+ * Sets the vertical scroll position of the ContentView.
+ * @param contentViewVerticalScroll The vertical scroll position.
+ */
+ private void setContentViewVerticalScroll(float contentViewVerticalScroll) {
+ mContentVerticalScroll = contentViewVerticalScroll;
+ }
+
+ /**
+ * Simulates a MotionEvent in the OverlayPanelEventFilter.
+ * @param action The event's action.
+ * @param x The event's x coordinate in dps.
+ * @param y The event's y coordinate in dps.
+ */
+ private void simulateEvent(int action, float x, float y) {
+ MotionEvent motionEvent = MotionEvent.obtain(0, 0, action, x * mDpToPx, y * mDpToPx, 0);
+ mEventFilter.onTouchEventInternal(motionEvent);
+ }
+
+ /**
+ * Simulates a MotionEvent.ACTION_DOWN in the OverlayPanelEventFilter.
+ * @param x The event's x coordinate in dps.
+ * @param y The event's y coordinate in dps.
+ */
+ private void simulateActionDownEvent(float x, float y) {
+ simulateEvent(MotionEvent.ACTION_DOWN, x, y);
+ }
+
+ /**
+ * Simulates a MotionEvent.ACTION_MOVE in the OverlayPanelEventFilter.
+ * @param x The event's x coordinate in dps.
+ * @param y The event's y coordinate in dps.
+ */
+ private void simulateActionMoveEvent(float x, float y) {
+ simulateEvent(MotionEvent.ACTION_MOVE, x, y);
+ }
+
+ /**
+ * Simulates a MotionEvent.ACTION_UP in the OverlayPanelEventFilter.
+ * @param x The event's x coordinate in dps.
+ * @param y The event's y coordinate in dps.
+ */
+ private void simulateActionUpEvent(float x, float y) {
+ simulateEvent(MotionEvent.ACTION_UP, x, y);
+ }
+}
« no previous file with comments | « chrome/android/java_sources.gni ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698