From 669265332898b9b323d38abd45b6fc776d86aed9 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 7 Dec 2022 23:58:35 -0800 Subject: [PATCH] Disable quickswitch for trackpad gestures Bug: 261815244 Test: make sure (1) if user starts by swiping up, disable quickswitch (they will land either in overview, home, or the current app) (2) if user starts by quick switching, cancel the gesture Change-Id: I6b59cec0089d5e6f22eee3241c6336345dd15dce --- .../android/quickstep/AbsSwipeUpHandler.java | 6 +++++- .../com/android/quickstep/GestureState.java | 15 +++++++++++++++ .../quickstep/OverviewCommandHelper.java | 3 ++- .../quickstep/TouchInteractionService.java | 10 +++++++--- .../OtherActivityInputConsumer.java | 19 ++++++++++++++----- 5 files changed, 43 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index ddc14b8adc..775d422336 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -2080,7 +2080,11 @@ public abstract class AbsSwipeUpHandler, runOnRecentsAnimationAndLauncherBound(() -> mRecentsView.setRecentsAnimationTargets(mRecentsAnimationController, mRecentsAnimationTargets)); - mRecentsViewScrollLinked = true; + + // Disable scrolling in RecentsView for trackpad gestures. + if (!mGestureState.isTrackpadGesture()) { + mRecentsViewScrollLinked = true; + } } private void onRecentsViewScroll() { diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index 31b78b3ec3..2b0623a67d 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -139,6 +139,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL private final BaseActivityInterface mActivityInterface; private final MultiStateCallback mStateCallback; private final int mGestureId; + private boolean mIsTrackpadGesture; private CachedTaskInfo mRunningTask; private GestureEndTarget mEndTarget; @@ -247,6 +248,20 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL return mGestureId; } + /** + * Sets if the gesture is is from the trackpad. + */ + public void setIsTrackpadGesture(boolean isTrackpadGesture) { + mIsTrackpadGesture = isTrackpadGesture; + } + + /** + * @return if the gesture is from the trackpad. + */ + public boolean isTrackpadGesture() { + return mIsTrackpadGesture; + } + /** * @return the running task for this gesture. */ diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index 99af0520b7..4325c6d850 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -218,7 +218,8 @@ public class OverviewCommandHelper { InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); } - GestureState gestureState = mService.createGestureState(GestureState.DEFAULT_STATE); + GestureState gestureState = mService.createGestureState(GestureState.DEFAULT_STATE, + false /* isTrackpadGesture */); gestureState.setHandlingAtomicEvent(true); AbsSwipeUpHandler interactionHandler = mService.getSwipeUpHandlerFactory() .newHandler(gestureState, cmd.createTime); diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 88df733779..ea7652eee1 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -628,7 +628,8 @@ public class TouchInteractionService extends Service // Clone the previous gesture state since onConsumerAboutToBeSwitched might trigger // onConsumerInactive and wipe the previous gesture state GestureState prevGestureState = new GestureState(mGestureState); - GestureState newGestureState = createGestureState(mGestureState); + GestureState newGestureState = createGestureState(mGestureState, + isTrackpadMotionEvent(event)); newGestureState.setSwipeUpStartTimeMs(SystemClock.uptimeMillis()); mConsumer.onConsumerAboutToBeSwitched(); mGestureState = newGestureState; @@ -637,7 +638,7 @@ public class TouchInteractionService extends Service } else if (LockedUserState.get(this).isUserUnlocked() && mDeviceState.isFullyGesturalNavMode() && mDeviceState.canTriggerAssistantAction(event)) { - mGestureState = createGestureState(mGestureState); + mGestureState = createGestureState(mGestureState, isTrackpadMotionEvent(event)); // Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we // should not interrupt it. QuickSwitch assumes that interruption can only // happen if the next gesture is also quick switch. @@ -715,7 +716,8 @@ public class TouchInteractionService extends Service } } - public GestureState createGestureState(GestureState previousGestureState) { + public GestureState createGestureState(GestureState previousGestureState, + boolean isTrackpadGesture) { final GestureState gestureState; TopTaskTracker.CachedTaskInfo taskInfo; if (mTaskAnimationManager.isRecentsAnimationRunning()) { @@ -732,6 +734,8 @@ public class TouchInteractionService extends Service taskInfo = TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false); gestureState.updateRunningTask(taskInfo); } + gestureState.setIsTrackpadGesture(isTrackpadGesture); + // Log initial state for the gesture. ActiveGestureLog.INSTANCE.addLog(new CompoundString("Current running task package name=") .append(taskInfo == null ? "no running task" : taskInfo.getPackageName())); diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 51c6621e0a..cd0d463cbb 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -205,7 +205,10 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } int edgeFlags = ev.getEdgeFlags(); ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR); - mRecentsViewDispatcher.dispatchEvent(ev); + // Disable scrolling in RecentsView for trackpad gestures. + if (!mGestureState.isTrackpadGesture()) { + mRecentsViewDispatcher.dispatchEvent(ev); + } ev.setEdgeFlags(edgeFlags); mVelocityTracker.addMovement(ev); @@ -289,9 +292,16 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (!mPassedPilferInputSlop) { if (passedSlop) { - if (mDisableHorizontalSwipe - && Math.abs(displacementX) > Math.abs(displacementY)) { - // Horizontal gesture is not allowed in this region + // Horizontal gesture is not allowed in this region + boolean isHorizontalSwipeWhenDisabled = + (mDisableHorizontalSwipe && Math.abs(displacementX) > Math.abs( + displacementY)); + // Do not allow quick switch for trackpad 3-finger gestures + // TODO(b/261815244): might need to impose stronger conditions for the swipe + // angle + boolean noQuickSwitchForTrackpadGesture = mGestureState.isTrackpadGesture() + && isLikelyToStartNewTask; + if (isHorizontalSwipeWhenDisabled || noQuickSwitchForTrackpadGesture) { forceCancelGesture(ev); break; } @@ -306,7 +316,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC if (!mPassedWindowMoveSlop) { mPassedWindowMoveSlop = true; mStartDisplacement = Math.min(displacement, -mTouchSlop); - } notifyGestureStarted(isLikelyToStartNewTask); }