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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ContextualSearchEventFilter.java

Issue 1716653002: Implement OverlayPanels as SceneOverlays (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix tests Created 4 years, 8 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
Index: chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ContextualSearchEventFilter.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ContextualSearchEventFilter.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ContextualSearchEventFilter.java
deleted file mode 100644
index 18fceee3e01af3e0e3e75075e3ade859025c330c..0000000000000000000000000000000000000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/ContextualSearchEventFilter.java
+++ /dev/null
@@ -1,545 +0,0 @@
-// Copyright 2015 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.layouts.eventfilter;
-
-import android.content.Context;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-
-import org.chromium.base.VisibleForTesting;
-import org.chromium.chrome.browser.compositor.bottombar.OverlayPanel;
-import org.chromium.chrome.browser.compositor.bottombar.OverlayPanelManager;
-
-import java.util.ArrayList;
-
-/**
- * The {@link GestureEventFilter} used when Contextual Search Layout is being shown. It filters
- * events that happen in the Search Content View area and propagates them to the appropriate
- * Content View Core via {@link EventFilterHost}. Events that happen outside that area are
- * propagated to the {@code ContextualSearchLayout} via {@code LayoutManagerPhone}.
- */
-public class ContextualSearchEventFilter extends GestureEventFilter {
-
- /**
- * The targets that can handle MotionEvents.
- */
- private enum EventTarget {
- UNDETERMINED,
- SEARCH_PANEL,
- SEARCH_CONTENT_VIEW
- }
-
- /**
- * The direction of the gesture.
- */
- private enum GestureOrientation {
- UNDETERMINED,
- HORIZONTAL,
- VERTICAL
- }
-
- /**
- * The boost factor that can be applied to prioritize vertical movements over horizontal ones.
- */
- private static final float VERTICAL_DETERMINATION_BOOST = 1.25f;
-
- /**
- * Manager to get the active OverlayPanel from.
- */
- private OverlayPanelManager mPanelManager;
-
- /**
- * The {@link GestureDetector} used to distinguish tap and scroll gestures.
- */
- private final GestureDetector mGestureDetector;
-
- /**
- * The target to propagate events to.
- */
- private EventTarget mEventTarget;
-
- /**
- * Whether the code is in the middle of the process of determining the event target.
- */
- private boolean mIsDeterminingEventTarget;
-
- /**
- * Whether the event target has been determined.
- */
- private boolean mHasDeterminedEventTarget;
-
- /**
- * The previous target the events were propagated to.
- */
- private EventTarget mPreviousEventTarget;
-
- /**
- * Whether the event target has changed since the last touch event.
- */
- private boolean mHasChangedEventTarget;
-
- /**
- * Whether the event target might change. This will be true in cases we know the overscroll
- * and/or underscroll might happen, which means we'll have to constantly monitor the event
- * targets in order to determine the exact moment the target has changed.
- */
- private boolean mMayChangeEventTarget;
-
- /**
- * Whether the gesture orientation has been determined.
- */
- private boolean mHasDeterminedGestureOrientation;
-
- /**
- * The current gesture orientation.
- */
- private GestureOrientation mGestureOrientation;
-
- /**
- * Whether the events are being recorded.
- */
- private boolean mIsRecordingEvents;
-
- /**
- * Whether the ACTION_DOWN that initiated the MotionEvent's stream was synthetic.
- */
- private boolean mWasActionDownEventSynthetic;
-
- /**
- * The X coordinate of the synthetic ACTION_DOWN MotionEvent.
- */
- private float mSyntheticActionDownX;
-
- /**
- * The Y coordinate of the synthetic ACTION_DOWN MotionEvent.
- */
- private float mSyntheticActionDownY;
-
- /**
- * The list of recorded events.
- */
- private final ArrayList<MotionEvent> mRecordedEvents = new ArrayList<MotionEvent>();
-
- /**
- * The initial Y position of the current gesture.
- */
- private float mInitialEventY;
-
- /**
- * The square of ViewConfiguration.getScaledTouchSlop() in pixels used to calculate whether
- * the finger has moved beyond the established threshold.
- */
- private final float mTouchSlopSquarePx;
-
- /**
- * Creates a {@link GestureEventFilter} with offset touch events.
- * @param context The {@link Context} for Android.
- * @param host The {@link EventFilterHost} for this event filter.
- * @param handler The {@link GestureHandler} for this event filter.
- * @param panelManager The {@link OverlayPanelManager} responsible for showing panels.
- */
- public ContextualSearchEventFilter(Context context, EventFilterHost host,
- GestureHandler handler, OverlayPanelManager panelManager) {
- super(context, host, handler, false, false);
-
- mGestureDetector = new GestureDetector(context, new InternalGestureDetector());
- mPanelManager = panelManager;
-
- // Store the square of the platform touch slop in pixels to use in the scroll detection.
- // See {@link ContextualSearchEventFilter#isDistanceGreaterThanTouchSlop}.
- float touchSlopPx = ViewConfiguration.get(context).getScaledTouchSlop();
- mTouchSlopSquarePx = touchSlopPx * touchSlopPx;
-
- reset();
- }
-
- /**
- * Gets the Search Content View's vertical scroll position. If the Search Content View
- * is not available it returns -1.
- * @return The Search Content View scroll position.
- */
- @VisibleForTesting
- protected float getSearchContentViewVerticalScroll() {
- OverlayPanel panel = mPanelManager.getActivePanel();
- if (panel == null) return 0;
-
- return panel.getContentVerticalScroll();
- }
-
- @Override
- public boolean onTouchEventInternal(MotionEvent e) {
- final int action = e.getActionMasked();
-
- if (!mIsDeterminingEventTarget && action == MotionEvent.ACTION_DOWN) {
- mInitialEventY = e.getY();
- OverlayPanel panel = mPanelManager.getActivePanel();
- if (panel != null && panel.isCoordinateInsideContent(
- e.getX() * mPxToDp, mInitialEventY * mPxToDp)) {
- // If the DOWN event happened inside the Search Content View, we'll need
- // to wait until the user has moved the finger beyond a certain threshold,
- // so we can determine the gesture's orientation and consequently be able
- // to tell if the Content View will accept the gesture.
- mIsDeterminingEventTarget = true;
- mMayChangeEventTarget = true;
- } else {
- // If the DOWN event happened outside the Search Content View, then we know
- // that the Search Panel will start handling the event right away.
- setEventTarget(EventTarget.SEARCH_PANEL);
- mMayChangeEventTarget = false;
- }
- }
-
- // Send the event to the GestureDetector so we can distinguish between scroll and tap.
- mGestureDetector.onTouchEvent(e);
-
- if (mHasDeterminedEventTarget) {
- // If the event target has been determined, resume pending events, then propagate
- // the current event to the appropriate target.
- resumeAndPropagateEvent(e);
- } else {
- // If the event target has not been determined, we need to record a copy of the event
- // until we are able to determine the event target.
- MotionEvent event = MotionEvent.obtain(e);
- mRecordedEvents.add(event);
- mIsRecordingEvents = true;
- }
-
- if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- reset();
- }
-
- return true;
- }
-
- /**
- * Resets the current and previous {@link EventTarget} as well the {@link GestureOrientation}
- * to the UNDETERMINED state.
- */
- private void reset() {
- mEventTarget = EventTarget.UNDETERMINED;
- mIsDeterminingEventTarget = false;
- mHasDeterminedEventTarget = false;
-
- mPreviousEventTarget = EventTarget.UNDETERMINED;
- mHasChangedEventTarget = false;
- mMayChangeEventTarget = false;
-
- mWasActionDownEventSynthetic = false;
-
- mGestureOrientation = GestureOrientation.UNDETERMINED;
- mHasDeterminedGestureOrientation = false;
- }
-
- /**
- * Resumes pending events then propagates the given event to the current {@link EventTarget}.
- *
- * Resuming events might consist in simply propagating previously recorded events if the
- * EventTarget was UNDETERMINED when the gesture started.
- *
- * For the case where the EventTarget has changed during the course of the gesture, we'll
- * need to simulate a gesture end in the previous target (by simulating an ACTION_CANCEL
- * event) and a gesture start in the new target (by simulating an ACTION_DOWN event).
- *
- * @param e The {@link MotionEvent} to be propagated after resuming the pending events.
- */
- private void resumeAndPropagateEvent(MotionEvent e) {
- OverlayPanel panel = mPanelManager.getActivePanel();
- if (panel == null) return;
-
- if (mIsRecordingEvents) {
- resumeRecordedEvents();
- }
-
- if (mHasChangedEventTarget) {
- // If the event target has changed since the beginning of the gesture, then we need
- // to send a ACTION_CANCEL to the previous event target to make sure it no longer
- // expects events.
- propagateAndRecycleEvent(copyEvent(e, MotionEvent.ACTION_CANCEL), mPreviousEventTarget);
-
- // Similarly we need to send an ACTION_DOWN to the new event target so subsequent
- // events can be analyzed properly by the Gesture Detector.
- MotionEvent syntheticActionDownEvent = copyEvent(e, MotionEvent.ACTION_DOWN);
-
- // Store the synthetic ACTION_DOWN coordinates to prevent unwanted taps from
- // happening. See {@link ContextualSearchEventFilter#propagateEventToSearchContentView}.
- mWasActionDownEventSynthetic = true;
- mSyntheticActionDownX = syntheticActionDownEvent.getX();
- mSyntheticActionDownY = syntheticActionDownEvent.getY() - panel.getContentY() / mPxToDp;
-
- propagateAndRecycleEvent(syntheticActionDownEvent, mEventTarget);
-
- mHasChangedEventTarget = false;
- }
-
- propagateEvent(e, mEventTarget);
- }
-
- /**
- * Resumes recorded events by propagating all of them to the current {@link EventTarget}.
- */
- private void resumeRecordedEvents() {
- for (int i = 0, size = mRecordedEvents.size(); i < size; i++) {
- propagateAndRecycleEvent(mRecordedEvents.get(i), mEventTarget);
- }
-
- mRecordedEvents.clear();
- mIsRecordingEvents = false;
- }
-
- /**
- * Propagates the given {@link MotionEvent} to the given {@link EventTarget}, recycling it
- * afterwards. This is intended for synthetic events only, those create by
- * {@link MotionEvent#obtain} or the helper methods
- * {@link ContextualSearchEventFilter#lockEventHorizontallty} and
- * {@link ContextualSearchEventFilter#copyEvent}.
- *
- * @param e The {@link MotionEvent} to be propagated.
- * @param target The {@link EventTarget} to propagate events to.
- */
- private void propagateAndRecycleEvent(MotionEvent e, EventTarget target) {
- propagateEvent(e, target);
- e.recycle();
- }
-
- /**
- * Propagates the given {@link MotionEvent} to the given {@link EventTarget}.
- * @param e The {@link MotionEvent} to be propagated.
- * @param target The {@link EventTarget} to propagate events to.
- */
- private void propagateEvent(MotionEvent e, EventTarget target) {
- if (target == EventTarget.SEARCH_PANEL) {
- super.onTouchEventInternal(e);
- } else if (target == EventTarget.SEARCH_CONTENT_VIEW) {
- propagateEventToSearchContentView(e);
- }
- }
-
- /**
- * Propagates the given {@link MotionEvent} to the Search Content View.
- * @param e The {@link MotionEvent} to be propagated.
- */
- @VisibleForTesting
- protected void propagateEventToSearchContentView(MotionEvent e) {
- OverlayPanel panel = mPanelManager.getActivePanel();
- if (panel == null) return;
-
- MotionEvent event = e;
- int action = event.getActionMasked();
- boolean isSyntheticEvent = false;
- if (mGestureOrientation == GestureOrientation.HORIZONTAL && !panel.isMaximized()) {
- // Ignores multitouch events to prevent the Search Result Page from from scrolling.
- if (action == MotionEvent.ACTION_POINTER_UP
- || action == MotionEvent.ACTION_POINTER_DOWN) {
- return;
- }
-
- // NOTE(pedrosimonetti): Lock horizontal motion, ignoring all vertical changes,
- // when the Panel is not maximized. This is to prevent the Search Result Page
- // from scrolling when side swiping on the expanded Panel. Also, note that the
- // method {@link ContextualSearchEventFilter#lockEventHorizontallty} will always
- // return an event with a single pointer, which is necessary to prevent
- // the app from crashing when the motion involves multiple pointers.
- // See: crbug.com/486901
- event = MotionEvent.obtain(
- e.getDownTime(),
- e.getEventTime(),
- // NOTE(pedrosimonetti): Use getActionMasked() to make sure we're not
- // send any pointer information to the event, given that getAction()
- // may have the pointer Id associated to it.
- e.getActionMasked(),
- e.getX(),
- mInitialEventY,
- e.getMetaState());
-
- isSyntheticEvent = true;
- }
-
- final float contentViewOffsetXPx = panel.getContentX() / mPxToDp;
- final float contentViewOffsetYPx = panel.getContentY() / mPxToDp;
-
- // Adjust the offset to be relative to the Search Contents View.
- event.offsetLocation(-contentViewOffsetXPx, -contentViewOffsetYPx);
-
- boolean wasEventCanceled = false;
- if (mWasActionDownEventSynthetic && action == MotionEvent.ACTION_UP) {
- float deltaX = event.getX() - mSyntheticActionDownX;
- float deltaY = event.getY() - mSyntheticActionDownY;
- // NOTE(pedrosimonetti): If the ACTION_DOWN event was synthetic and the distance
- // between it and the ACTION_UP event was short, then we should synthesize an
- // ACTION_CANCEL event to prevent a Tap gesture from being triggered on the Search
- // Content View. See crbug.com/408654
- if (!isDistanceGreaterThanTouchSlop(deltaX, deltaY)) {
- event.setAction(MotionEvent.ACTION_CANCEL);
- mHost.propagateEvent(event);
- wasEventCanceled = true;
- }
- } else if (action == MotionEvent.ACTION_DOWN) {
- panel.onTouchSearchContentViewAck();
- }
-
- // Propagate the event to the appropriate view
- if (!wasEventCanceled) mHost.propagateEvent(event);
-
- // Synthetic events should be recycled.
- if (isSyntheticEvent) event.recycle();
- }
-
- /**
- * Creates a {@link MotionEvent} inheriting from a given |e| event.
- * @param e The {@link MotionEvent} to inherit properties from.
- * @param action The MotionEvent's Action to be used.
- * @return A new {@link MotionEvent}.
- */
- private MotionEvent copyEvent(MotionEvent e, int action) {
- MotionEvent event = MotionEvent.obtain(e);
- event.setAction(action);
- return event;
- }
-
- /**
- * Handles the tap event, determining the event target.
- * @param e The tap {@link MotionEvent}.
- * @return Whether the event has been consumed.
- */
- private boolean handleSingleTapUp(MotionEvent e) {
- OverlayPanel panel = mPanelManager.getActivePanel();
- if (panel != null) {
- setEventTarget(panel.isCoordinateInsideContent(
- e.getX() * mPxToDp, e.getY() * mPxToDp)
- ? EventTarget.SEARCH_CONTENT_VIEW : EventTarget.SEARCH_PANEL);
- }
- return false;
- }
-
- /**
- * Handles the scroll event, determining the gesture orientation and event target,
- * when appropriate.
- * @param e1 The first down {@link MotionEvent} that started the scrolling.
- * @param e2 The move {@link MotionEvent} that triggered the current scroll.
- * @param distanceY The distance along the Y axis that has been scrolled since the last call
- * to handleScroll.
- * @return Whether the event has been consumed.
- */
- private boolean handleScroll(MotionEvent e1, MotionEvent e2, float distanceY) {
- // Only determines the gesture orientation if it hasn't been determined yet,
- // affectively "locking" the orientation once the gesture has started.
- if (!mHasDeterminedGestureOrientation && isDistanceGreaterThanTouchSlop(e1, e2)) {
- determineGestureOrientation(e1, e2);
- }
-
- // Only determines the event target after determining the gesture orientation and
- // if it hasn't been determined yet or if changing the event target during the
- // middle of the gesture is supported. This will allow a smooth transition from
- // swiping the Panel and scrolling the Search Content View.
- final boolean mayChangeEventTarget = mMayChangeEventTarget && e2.getPointerCount() == 1;
- if (mHasDeterminedGestureOrientation
- && (!mHasDeterminedEventTarget || mayChangeEventTarget)) {
- determineEventTarget(distanceY);
- }
-
- return false;
- }
-
- /**
- * Determines the gesture orientation.
- * @param e1 The first down {@link MotionEvent} that started the scrolling.
- * @param e2 The move {@link MotionEvent} that triggered the current scroll.
- */
- private void determineGestureOrientation(MotionEvent e1, MotionEvent e2) {
- float deltaX = Math.abs(e2.getX() - e1.getX());
- float deltaY = Math.abs(e2.getY() - e1.getY());
- mGestureOrientation = deltaY * VERTICAL_DETERMINATION_BOOST > deltaX
- ? GestureOrientation.VERTICAL : GestureOrientation.HORIZONTAL;
- mHasDeterminedGestureOrientation = true;
- }
-
- /**
- * Determines the target to propagate events to. This will not only update the
- * {@code mEventTarget} but also save the previous target and determine whether the
- * target has changed.
- * @param distanceY The distance along the Y axis that has been scrolled since the last call
- * to handleScroll.
- */
- private void determineEventTarget(float distanceY) {
- boolean isVertical = mGestureOrientation == GestureOrientation.VERTICAL;
-
- boolean shouldPropagateEventsToSearchPanel;
- OverlayPanel panel = mPanelManager.getActivePanel();
- if (panel != null && panel.isMaximized()) {
- // Allow overscroll in the Search Content View to move the Search Panel instead
- // of scrolling the Search Result Page.
- boolean isMovingDown = distanceY < 0;
- shouldPropagateEventsToSearchPanel = isVertical
- && isMovingDown
- && getSearchContentViewVerticalScroll() == 0;
- } else {
- // Only allow horizontal movements to be propagated to the Search Content View
- // when the Panel is expanded (that is, not maximized).
- shouldPropagateEventsToSearchPanel = isVertical;
-
- // If the gesture is horizontal, then we know that the event target won't change.
- if (!isVertical) mMayChangeEventTarget = false;
- }
-
- EventTarget target = shouldPropagateEventsToSearchPanel
- ? EventTarget.SEARCH_PANEL : EventTarget.SEARCH_CONTENT_VIEW;
-
- if (target != mEventTarget) {
- mPreviousEventTarget = mEventTarget;
- setEventTarget(target);
-
- mHasChangedEventTarget = mEventTarget != mPreviousEventTarget
- && mPreviousEventTarget != EventTarget.UNDETERMINED;
- }
- }
-
- /**
- * Sets the {@link EventTarget}.
- * @param target The {@link EventTarget} to be set.
- */
- private void setEventTarget(EventTarget target) {
- mEventTarget = target;
-
- mIsDeterminingEventTarget = false;
- mHasDeterminedEventTarget = true;
- }
-
- /**
- * @param e1 The first down {@link MotionEvent} that started the scrolling.
- * @param e2 The move {@link MotionEvent} that triggered the current scroll.
- * @return Whether the distance is greater than the touch slop threshold.
- */
- private boolean isDistanceGreaterThanTouchSlop(MotionEvent e1, MotionEvent e2) {
- float deltaX = e2.getX() - e1.getX();
- float deltaY = e2.getY() - e1.getY();
- // Check if the distance between the events |e1| and |e2| is greater than the touch slop.
- return isDistanceGreaterThanTouchSlop(deltaX, deltaY);
- }
-
- /**
- * @param deltaX The delta X in pixels.
- * @param deltaY The delta Y in pixels.
- * @return Whether the distance is greater than the touch slop threshold.
- */
- private boolean isDistanceGreaterThanTouchSlop(float deltaX, float deltaY) {
- return deltaX * deltaX + deltaY * deltaY > mTouchSlopSquarePx;
- }
-
- /**
- * Internal GestureDetector class that is responsible for determining the event target.
- */
- private class InternalGestureDetector extends GestureDetector.SimpleOnGestureListener {
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- return handleSingleTapUp(e);
- }
-
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
- return handleScroll(e1, e2, distanceY);
- }
- }
-}

Powered by Google App Engine
This is Rietveld 408576698