Merge "Updating the touch proxy logic:" into ub-launcher3-qt-dev
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
index b803071..32e0e48 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/OverviewInputConsumer.java
@@ -15,24 +15,20 @@
*/
package com.android.quickstep;
-import static android.view.MotionEvent.ACTION_CANCEL;
-import static android.view.MotionEvent.ACTION_DOWN;
-import static android.view.MotionEvent.ACTION_MOVE;
-import static android.view.MotionEvent.ACTION_UP;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
-import android.graphics.PointF;
import android.view.KeyEvent;
import android.view.MotionEvent;
-import android.view.ViewConfiguration;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.Utilities;
import com.android.launcher3.views.BaseDragLayer;
-import com.android.quickstep.util.CachedEventDispatcher;
import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputMonitorCompat;
+
+import androidx.annotation.Nullable;
/**
* Input consumer for handling touch on the recents/Launcher activity.
@@ -40,24 +36,27 @@
public class OverviewInputConsumer<T extends BaseDraggingActivity>
implements InputConsumer {
- private final CachedEventDispatcher mCachedEventDispatcher = new CachedEventDispatcher();
private final T mActivity;
private final BaseDragLayer mTarget;
+ private final InputMonitorCompat mInputMonitor;
+
private final int[] mLocationOnScreen = new int[2];
- private final PointF mDownPos = new PointF();
- private final int mTouchSlopSquared;
+ private final boolean mProxyTouch;
private final boolean mStartingInActivityBounds;
+ private boolean mTargetHandledTouch;
- private boolean mTrackingStarted = false;
- private boolean mInvalidated = false;
-
- OverviewInputConsumer(T activity, boolean startingInActivityBounds) {
+ OverviewInputConsumer(T activity, @Nullable InputMonitorCompat inputMonitor,
+ boolean startingInActivityBounds) {
mActivity = activity;
- mTarget = activity.getDragLayer();
- int touchSlop = ViewConfiguration.get(mActivity).getScaledTouchSlop();
- mTouchSlopSquared = touchSlop * touchSlop;
+ mInputMonitor = inputMonitor;
mStartingInActivityBounds = startingInActivityBounds;
+
+ mTarget = activity.getDragLayer();
+ if (!startingInActivityBounds) {
+ mTarget.getLocationOnScreen(mLocationOnScreen);
+ }
+ mProxyTouch = mTarget.prepareProxyEventStarting();
}
@Override
@@ -67,45 +66,29 @@
@Override
public void onMotionEvent(MotionEvent ev) {
- if (mInvalidated) {
+ if (!mProxyTouch) {
return;
}
- mCachedEventDispatcher.dispatchEvent(ev);
- int action = ev.getActionMasked();
- if (action == ACTION_DOWN) {
- if (mStartingInActivityBounds) {
- startTouchTracking(ev, false /* updateLocationOffset */,
- false /* closeActiveWindows */);
- return;
- }
- mTrackingStarted = false;
- mDownPos.set(ev.getX(), ev.getY());
- } else if (!mTrackingStarted) {
- switch (action) {
- case ACTION_CANCEL:
- case ACTION_UP:
- startTouchTracking(ev, true /* updateLocationOffset */,
- false /* closeActiveWindows */);
- break;
- case ACTION_MOVE: {
- float x = ev.getX() - mDownPos.x;
- float y = ev.getY() - mDownPos.y;
- double hypotSquared = x * x + y * y;
- if (hypotSquared >= mTouchSlopSquared) {
- // Start tracking only when touch slop is crossed.
- startTouchTracking(ev, true /* updateLocationOffset */,
- true /* closeActiveWindows */);
- }
- }
- }
+
+ int flags = ev.getEdgeFlags();
+ if (!mStartingInActivityBounds) {
+ ev.setEdgeFlags(flags | Utilities.EDGE_NAV_BAR);
}
+ ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
+ boolean handled = mTarget.proxyTouchEvent(ev);
+ ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
+ ev.setEdgeFlags(flags);
- if (action == ACTION_UP || action == ACTION_CANCEL) {
- mInvalidated = true;
-
- // Set an empty consumer to that all the cached events are cleared
- if (!mCachedEventDispatcher.hasConsumer()) {
- mCachedEventDispatcher.setConsumer(motionEvent -> { });
+ if (!mTargetHandledTouch && handled) {
+ mTargetHandledTouch = true;
+ if (!mStartingInActivityBounds) {
+ OverviewCallbacks.get(mActivity).closeAllWindows();
+ ActivityManagerWrapper.getInstance()
+ .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+ TOUCH_INTERACTION_LOG.addLog("startQuickstep");
+ }
+ if (mInputMonitor != null) {
+ mInputMonitor.pilferPointers();
}
}
}
@@ -117,42 +100,12 @@
}
}
- private void startTouchTracking(MotionEvent ev, boolean updateLocationOffset,
- boolean closeActiveWindows) {
- if (updateLocationOffset) {
- mTarget.getLocationOnScreen(mLocationOnScreen);
- }
-
- if (closeActiveWindows) {
- OverviewCallbacks.get(mActivity).closeAllWindows();
- ActivityManagerWrapper.getInstance()
- .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- TOUCH_INTERACTION_LOG.addLog("startQuickstep");
- }
-
- mTrackingStarted = true;
- mCachedEventDispatcher.setConsumer(this::sendEvent);
-
- }
-
- private void sendEvent(MotionEvent ev) {
- if (mInvalidated) {
- return;
- }
- int flags = ev.getEdgeFlags();
- ev.setEdgeFlags(flags | Utilities.EDGE_NAV_BAR);
- ev.offsetLocation(-mLocationOnScreen[0], -mLocationOnScreen[1]);
- mInvalidated = !mTarget.dispatchTouchEvent(this, ev);
- ev.offsetLocation(mLocationOnScreen[0], mLocationOnScreen[1]);
- ev.setEdgeFlags(flags);
- }
-
public static InputConsumer newInstance(ActivityControlHelper activityHelper,
- boolean startingInActivityBounds) {
+ @Nullable InputMonitorCompat inputMonitor, boolean startingInActivityBounds) {
BaseDraggingActivity activity = activityHelper.getCreatedActivity();
if (activity == null) {
return InputConsumer.NO_OP;
}
- return new OverviewInputConsumer(activity, startingInActivityBounds);
+ return new OverviewInputConsumer(activity, inputMonitor, startingInActivityBounds);
}
}
\ No newline at end of file
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index fc3f332..b62bac6 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -468,10 +468,10 @@
mInputMonitorCompat, activityControl);
} else if (mSwipeSharedState.goingToLauncher || activityControl.isResumed()) {
- return OverviewInputConsumer.newInstance(activityControl, false);
+ return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
} else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
activityControl.isInLiveTileMode()) {
- return OverviewInputConsumer.newInstance(activityControl, false);
+ return OverviewInputConsumer.newInstance(activityControl, mInputMonitorCompat, false);
} else {
return createOtherActivityInputConsumer(event, runningTaskInfo);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index afc4fcb..4df1b15 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -802,7 +802,7 @@
setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
}
- return OverviewInputConsumer.newInstance(mActivityControlHelper, true);
+ return OverviewInputConsumer.newInstance(mActivityControlHelper, null, true);
}
@UiThread
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
index 777e592..09d323e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/fallback/RecentsRootView.java
@@ -17,18 +17,13 @@
import android.annotation.TargetApi;
import android.content.Context;
-import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.ViewDebug;
import android.view.WindowInsets;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.util.Themes;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.BaseDragLayer;
@@ -39,9 +34,6 @@
private static final int MIN_SIZE = 10;
private final RecentsActivity mActivity;
- @ViewDebug.ExportedProperty(category = "launcher")
- private final RectF mTouchExcludeRegion = new RectF();
-
private final Point mLastKnownSize = new Point(MIN_SIZE, MIN_SIZE);
public RecentsRootView(Context context, AttributeSet attrs) {
@@ -100,26 +92,7 @@
@Override
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
- if (Utilities.ATLEAST_Q) {
- Insets gestureInsets = insets.getMandatorySystemGestureInsets();
- mTouchExcludeRegion.set(gestureInsets.left, gestureInsets.top,
- gestureInsets.right, gestureInsets.bottom);
- }
+ updateTouchExcludeRegion(insets);
return super.dispatchApplyWindowInsets(insets);
}
-
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- float x = ev.getX();
- float y = ev.getY();
- if (y < mTouchExcludeRegion.top
- || x < mTouchExcludeRegion.left
- || x > (getWidth() - mTouchExcludeRegion.right)
- || y > (getHeight() - mTouchExcludeRegion.bottom)) {
- return false;
- }
- }
- return super.dispatchTouchEvent(ev);
- }
}
\ No newline at end of file
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
index e6c2d0c..90e673b 100644
--- a/src/com/android/launcher3/LauncherRootView.java
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -8,13 +8,10 @@
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.Insets;
import android.graphics.Paint;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
import android.view.WindowInsets;
@@ -32,9 +29,6 @@
private final Rect mConsumedInsets = new Rect();
@ViewDebug.ExportedProperty(category = "launcher")
- private final RectF mTouchExcludeRegion = new RectF();
-
- @ViewDebug.ExportedProperty(category = "launcher")
private static final List<Rect> SYSTEM_GESTURE_EXCLUSION_RECT =
Collections.singletonList(new Rect());
@@ -164,30 +158,11 @@
@Override
public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
- if (Utilities.ATLEAST_Q) {
- Insets gestureInsets = insets.getMandatorySystemGestureInsets();
- mTouchExcludeRegion.set(gestureInsets.left, gestureInsets.top,
- gestureInsets.right, gestureInsets.bottom);
- }
+ mLauncher.getDragLayer().updateTouchExcludeRegion(insets);
return super.dispatchApplyWindowInsets(insets);
}
@Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- float x = ev.getX();
- float y = ev.getY();
- if (y < mTouchExcludeRegion.top
- || x < mTouchExcludeRegion.left
- || x > (getWidth() - mTouchExcludeRegion.right)
- || y > (getHeight() - mTouchExcludeRegion.bottom)) {
- return false;
- }
- }
- return super.dispatchTouchEvent(ev);
- }
-
- @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
SYSTEM_GESTURE_EXCLUSION_RECT.get(0).set(l, t, r, b);
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 593dbd4..c7d93fe 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -22,7 +22,6 @@
import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import static com.android.launcher3.Utilities.EDGE_NAV_BAR;
import android.animation.AnimatorSet;
import android.animation.LayoutTransition;
@@ -173,8 +172,7 @@
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
BaseDragLayer dl = getPopupContainer();
- final boolean cameFromNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
- if (!cameFromNavBar && !dl.isEventOverView(this, ev)) {
+ if (!dl.isEventOverView(this, ev)) {
mLauncher.getUserEventDispatcher().logActionTapOutside(
LoggerUtils.newContainerTarget(ContainerType.DEEPSHORTCUTS));
close(true);
diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java
index 66cd536..8a15220 100644
--- a/src/com/android/launcher3/views/BaseDragLayer.java
+++ b/src/com/android/launcher3/views/BaseDragLayer.java
@@ -22,13 +22,19 @@
import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
+import android.annotation.TargetApi;
import android.content.Context;
+import android.graphics.Insets;
import android.graphics.Rect;
+import android.graphics.RectF;
+import android.os.Build;
import android.util.AttributeSet;
import android.util.Property;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewDebug;
import android.view.ViewGroup;
+import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
@@ -74,18 +80,32 @@
}
};
+ // Touch is being dispatched through the normal view dispatch system
+ private static final int TOUCH_DISPATCHING_VIEW = 1 << 0;
+ // Touch is being dispatched through the normal view dispatch system, and started at the
+ // system gesture region
+ private static final int TOUCH_DISPATCHING_GESTURE = 1 << 1;
+ // Touch is being dispatched through a proxy from InputMonitor
+ private static final int TOUCH_DISPATCHING_PROXY = 1 << 2;
+
protected final int[] mTmpXY = new int[2];
protected final Rect mHitRect = new Rect();
+ @ViewDebug.ExportedProperty(category = "launcher")
+ private final RectF mSystemGestureRegion = new RectF();
+ private int mTouchDispatchState = 0;
+
protected final T mActivity;
private final MultiValueAlpha mMultiValueAlpha;
+ // All the touch controllers for the view
protected TouchController[] mControllers;
+ // Touch controller which is currently active for the normal view dispatch
protected TouchController mActiveController;
- private TouchCompleteListener mTouchCompleteListener;
+ // Touch controller which is being used for the proxy events
+ protected TouchController mProxyTouchController;
- // Object controlling the current touch interaction
- private Object mCurrentTouchOwner;
+ private TouchCompleteListener mTouchCompleteListener;
public BaseDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) {
super(context, attrs);
@@ -113,30 +133,36 @@
return findActiveController(ev);
}
+ private TouchController findControllerToHandleTouch(MotionEvent ev) {
+ AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
+ if (topView != null && topView.onControllerInterceptTouchEvent(ev)) {
+ return topView;
+ }
+
+ for (TouchController controller : mControllers) {
+ if (controller.onControllerInterceptTouchEvent(ev)) {
+ return controller;
+ }
+ }
+ return null;
+ }
+
protected boolean findActiveController(MotionEvent ev) {
if (com.android.launcher3.TestProtocol.sDebugTracing) {
android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
"mActiveController = null");
}
mActiveController = null;
+ if ((mTouchDispatchState & (TOUCH_DISPATCHING_GESTURE | TOUCH_DISPATCHING_PROXY)) == 0) {
+ // Only look for controllers if we are not dispatching from gesture area and proxy is
+ // not active
+ mActiveController = findControllerToHandleTouch(ev);
- AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
- if (topView != null && topView.onControllerInterceptTouchEvent(ev)) {
- if (com.android.launcher3.TestProtocol.sDebugTracing) {
- android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "setting controller1: " + topView.getClass().getSimpleName());
- }
- mActiveController = topView;
- return true;
- }
-
- for (TouchController controller : mControllers) {
- if (controller.onControllerInterceptTouchEvent(ev)) {
+ if (mActiveController != null) {
if (com.android.launcher3.TestProtocol.sDebugTracing) {
android.util.Log.d(com.android.launcher3.TestProtocol.NO_DRAG_TAG,
- "setting controller1: " + controller.getClass().getSimpleName());
+ "setting controller1: " + mActiveController.getClass().getSimpleName());
}
- mActiveController = controller;
return true;
}
}
@@ -223,40 +249,75 @@
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
- return dispatchTouchEvent(this, ev);
- }
+ switch (ev.getAction()) {
+ case ACTION_DOWN: {
+ float x = ev.getX();
+ float y = ev.getY();
+ mTouchDispatchState |= TOUCH_DISPATCHING_VIEW;
- public boolean dispatchTouchEvent(Object caller, MotionEvent ev) {
- return verifyTouchDispatch(caller, ev) && super.dispatchTouchEvent(ev);
+ if ((y < mSystemGestureRegion.top
+ || x < mSystemGestureRegion.left
+ || x > (getWidth() - mSystemGestureRegion.right)
+ || y > (getHeight() - mSystemGestureRegion.bottom))) {
+ mTouchDispatchState |= TOUCH_DISPATCHING_GESTURE;
+ } else {
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_GESTURE;
+ }
+ break;
+ }
+ case ACTION_CANCEL:
+ case ACTION_UP:
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_GESTURE;
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_VIEW;
+ break;
+ }
+ super.dispatchTouchEvent(ev);
+
+ // We want to get all events so that mTouchDispatchSource is maintained properly
+ return true;
}
/**
- * Returns true if the {@param caller} is allowed to dispatch {@param ev} on this view,
- * false otherwise.
+ * Called before we are about to receive proxy events.
+ *
+ * @return false if we can't handle proxy at this time
*/
- private boolean verifyTouchDispatch(Object caller, MotionEvent ev) {
- int action = ev.getAction();
- if (action == ACTION_DOWN) {
- if (mCurrentTouchOwner != null) {
- // Another touch in progress.
- ev.setAction(ACTION_CANCEL);
- super.dispatchTouchEvent(ev);
- ev.setAction(action);
- }
- mCurrentTouchOwner = caller;
- return true;
- }
- if (mCurrentTouchOwner != caller) {
- // Someone else is controlling the touch
+ public boolean prepareProxyEventStarting() {
+ mProxyTouchController = null;
+ if ((mTouchDispatchState & TOUCH_DISPATCHING_VIEW) != 0 && mActiveController != null) {
+ // We are already dispatching using view system and have an active controller, we can't
+ // handle another controller.
+
+ // This flag was already cleared in proxy ACTION_UP or ACTION_CANCEL. Added here just
+ // to be safe
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_PROXY;
return false;
}
- if (action == ACTION_UP || action == ACTION_CANCEL) {
- mCurrentTouchOwner = null;
- }
+
+ mTouchDispatchState |= TOUCH_DISPATCHING_PROXY;
return true;
}
/**
+ * Proxies the touch events to the gesture handlers
+ */
+ public boolean proxyTouchEvent(MotionEvent ev) {
+ boolean handled;
+ if (mProxyTouchController != null) {
+ handled = mProxyTouchController.onControllerTouchEvent(ev);
+ } else {
+ mProxyTouchController = findControllerToHandleTouch(ev);
+ handled = mProxyTouchController != null;
+ }
+ int action = ev.getAction();
+ if (action == ACTION_UP || action == ACTION_CANCEL) {
+ mProxyTouchController = null;
+ mTouchDispatchState &= ~TOUCH_DISPATCHING_PROXY;
+ }
+ return handled;
+ }
+
+ /**
* Determine the rect of the descendant in this DragLayer's coordinates
*
* @param descendant The descendant whose coordinates we want to find.
@@ -423,4 +484,13 @@
}
}
}
+
+ @TargetApi(Build.VERSION_CODES.Q)
+ public void updateTouchExcludeRegion(WindowInsets insets) {
+ if (Utilities.ATLEAST_Q) {
+ Insets gestureInsets = insets.getMandatorySystemGestureInsets();
+ mSystemGestureRegion.set(gestureInsets.left, gestureInsets.top,
+ gestureInsets.right, gestureInsets.bottom);
+ }
+ }
}