diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java index 6e4a40843f..d34b604a76 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/BaseSwipeUpHandler.java @@ -22,22 +22,32 @@ import static com.android.launcher3.anim.Interpolators.DEACCEL; import static com.android.quickstep.TouchInteractionService.BACKGROUND_EXECUTOR; import android.annotation.TargetApi; +import android.app.ActivityManager.RunningTaskInfo; import android.content.Context; +import android.graphics.PointF; import android.os.Build; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; +import android.view.MotionEvent; import android.view.animation.Interpolator; import com.android.launcher3.Utilities; +import com.android.launcher3.graphics.RotationMode; import com.android.quickstep.util.ClipAnimationHelper; import com.android.quickstep.util.ClipAnimationHelper.TransformParams; +import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; +import com.android.quickstep.views.RecentsView; + +import java.util.function.Consumer; + +import androidx.annotation.UiThread; /** * Base class for swipe up handler with some utility methods */ @TargetApi(Build.VERSION_CODES.Q) -public abstract class BaseSwipeUpHandler { +public abstract class BaseSwipeUpHandler implements SwipeAnimationListener { // Start resisting when swiping past this factor of mTransitionDragLength. private static final float DRAG_LENGTH_FACTOR_START_PULLBACK = 1.4f; @@ -57,6 +67,16 @@ public abstract class BaseSwipeUpHandler { private final Vibrator mVibrator; + // Shift in the range of [0, 1]. + // 0 => preview snapShot is completely visible, and hotseat is completely translated down + // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely + // visible. + protected final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift); + + protected RecentsView mRecentsView; + + protected Runnable mGestureEndCallback; + protected BaseSwipeUpHandler(Context context) { mContext = context; mClipAnimationHelper = new ClipAnimationHelper(context); @@ -80,14 +100,20 @@ public abstract class BaseSwipeUpHandler { BACKGROUND_EXECUTOR.execute(() -> mVibrator.vibrate(effect)); } - protected float getShiftForDisplacement(float displacement) { + public Consumer getRecentsViewDispatcher(RotationMode rotationMode) { + return mRecentsView != null ? mRecentsView.getEventDispatcher(rotationMode) : null; + } + + @UiThread + public void updateDisplacement(float displacement) { // We are moving in the negative x/y direction displacement = -displacement; + float shift; if (displacement > mTransitionDragLength * mDragLengthFactor && mTransitionDragLength > 0) { - return mDragLengthFactor; + shift = mDragLengthFactor; } else { float translation = Math.max(displacement, 0); - float shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; + shift = mTransitionDragLength == 0 ? 0 : translation / mTransitionDragLength; if (shift > DRAG_LENGTH_FACTOR_START_PULLBACK) { float pullbackProgress = Utilities.getProgress(shift, DRAG_LENGTH_FACTOR_START_PULLBACK, mDragLengthFactor); @@ -95,7 +121,44 @@ public abstract class BaseSwipeUpHandler { shift = DRAG_LENGTH_FACTOR_START_PULLBACK + pullbackProgress * (DRAG_LENGTH_FACTOR_MAX_PULLBACK - DRAG_LENGTH_FACTOR_START_PULLBACK); } - return shift; } + + mCurrentShift.updateValue(shift); + } + + public void setGestureEndCallback(Runnable gestureEndCallback) { + mGestureEndCallback = gestureEndCallback; + } + + /** + * Called when the value of {@link #mCurrentShift} changes + */ + public abstract void updateFinalShift(); + + + /** + * Called when motion pause is detected + */ + public abstract void onMotionPauseChanged(boolean isPaused); + + @UiThread + public void onGestureStarted() { } + + @UiThread + public abstract void onGestureCancelled(); + + @UiThread + public abstract void onGestureEnded(float endVelocity, PointF velocity, PointF downPos); + + public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { } + + public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { } + + public void initWhenReady() { } + + public interface Factory { + + BaseSwipeUpHandler newHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture); } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java index 52e8ba26d0..61767e5f74 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/RecentsActivity.java @@ -199,6 +199,12 @@ public final class RecentsActivity extends BaseRecentsActivity { mFallbackRecentsView.resetTaskVisuals(); } + @Override + protected void onStop() { + super.onStop(); + mFallbackRecentsView.reset(); + } + public void onTaskLaunched() { mFallbackRecentsView.resetTaskVisuals(); } 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 0ef2f5c5ad..fafa4d34ca 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -239,6 +239,11 @@ public class TouchInteractionService extends Service implements private final InputConsumer mResetGestureInputConsumer = new ResetGestureInputConsumer(sSwipeSharedState); + private final BaseSwipeUpHandler.Factory mWindowTreansformFactory = + this::createWindowTransformSwipeHandler; + private final BaseSwipeUpHandler.Factory mFallbackNoButtonFactory = + this::createFallbackNoButtonSwipeHandler; + private ActivityManagerWrapper mAM; private RecentsModel mRecentsModel; private ISystemUiProxy mISystemUiProxy; @@ -623,10 +628,6 @@ public class TouchInteractionService extends Service implements } else if (mGestureBlockingActivity != null && runningTaskInfo != null && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) { return mResetGestureInputConsumer; - } else if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { - return new FallbackNoButtonInputConsumer(this, activityControl, - mInputMonitorCompat, sSwipeSharedState, mSwipeTouchRegion, - mOverviewComponentObserver, disableHorizontalSwipe(event), runningTaskInfo); } else { return createOtherActivityInputConsumer(event, runningTaskInfo); } @@ -639,17 +640,28 @@ public class TouchInteractionService extends Service implements && exclusionRegion.contains((int) event.getX(), (int) event.getY()); } - private OtherActivityInputConsumer createOtherActivityInputConsumer(MotionEvent event, + private InputConsumer createOtherActivityInputConsumer(MotionEvent event, RunningTaskInfo runningTaskInfo) { - final ActivityControlHelper activityControl = - mOverviewComponentObserver.getActivityControlHelper(); - boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event); - return new OtherActivityInputConsumer(this, runningTaskInfo, mRecentsModel, - mOverviewComponentObserver.getOverviewIntent(), activityControl, - shouldDefer, mOverviewCallbacks, mInputConsumer, this::onConsumerInactive, + final boolean shouldDefer; + final BaseSwipeUpHandler.Factory factory; + final Intent homeIntent; + + if (mMode == Mode.NO_BUTTON && !mOverviewComponentObserver.isHomeAndOverviewSame()) { + shouldDefer = true; + factory = mFallbackNoButtonFactory; + homeIntent = mOverviewComponentObserver.getHomeIntent(); + } else { + shouldDefer = mOverviewComponentObserver.getActivityControlHelper() + .deferStartingActivity(mActiveNavBarRegion, event); + factory = mWindowTreansformFactory; + homeIntent = mOverviewComponentObserver.getOverviewIntent(); + } + + return new OtherActivityInputConsumer(this, runningTaskInfo, homeIntent, + shouldDefer, mOverviewCallbacks, this::onConsumerInactive, sSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, - disableHorizontalSwipe(event)); + disableHorizontalSwipe(event), factory); } private InputConsumer createDeviceLockedInputConsumer(RunningTaskInfo taskInfo) { @@ -788,6 +800,19 @@ public class TouchInteractionService extends Service implements } } + private BaseSwipeUpHandler createWindowTransformSwipeHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture) { + return new WindowTransformSwipeHandler( + runningTask, this, touchTimeMs, + mOverviewComponentObserver.getActivityControlHelper(), + continuingLastGesture, mInputConsumer, mRecentsModel); + } + + private BaseSwipeUpHandler createFallbackNoButtonSwipeHandler(RunningTaskInfo runningTask, + long touchTimeMs, boolean continuingLastGesture) { + return new FallbackNoButtonInputConsumer(this, mOverviewComponentObserver, runningTask); + } + public static void startRecentsActivityAsync(Intent intent, RecentsAnimationListener listener) { BACKGROUND_EXECUTOR.execute(() -> ActivityManagerWrapper.getInstance() .startRecentsActivity(intent, null, listener, null, null)); 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 da9c6cb5fe..9684eeca2f 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -58,7 +58,6 @@ import android.os.Handler; import android.os.Looper; import android.os.SystemClock; import android.util.Log; -import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewTreeObserver.OnDrawListener; @@ -66,10 +65,6 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.view.animation.Interpolator; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.UiThread; - import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.DeviceProfile; @@ -79,7 +74,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.Interpolators; -import com.android.launcher3.graphics.RotationMode; import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; @@ -99,9 +93,7 @@ import com.android.quickstep.util.ClipAnimationHelper.TargetAlphaProvider; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RemoteAnimationTargetSet; import com.android.quickstep.util.SwipeAnimationTargetSet; -import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.quickstep.views.LiveTileOverlay; -import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InputConsumerController; @@ -110,11 +102,12 @@ import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; import com.android.systemui.shared.system.WindowCallbacksCompat; -import java.util.function.Consumer; +import androidx.annotation.NonNull; +import androidx.annotation.UiThread; @TargetApi(Build.VERSION_CODES.O) public class WindowTransformSwipeHandler extends BaseSwipeUpHandler - implements SwipeAnimationListener, OnApplyWindowInsetsListener { + implements OnApplyWindowInsetsListener { private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName(); private static final Rect TEMP_RECT = new Rect(); @@ -222,18 +215,12 @@ public class WindowTransformSwipeHandler extends */ private static final int LOG_NO_OP_PAGE_INDEX = -1; - private Runnable mGestureEndCallback; private GestureEndTarget mGestureEndTarget; // Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise private RunningWindowAnim mRunningWindowAnim; private boolean mIsShelfPeeking; private DeviceProfile mDp; - // Shift in the range of [0, 1]. - // 0 => preview snapShot is completely visible, and hotseat is completely translated down - // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely - // visible. - private final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift); private boolean mContinuingLastGesture; // To avoid UI jump when gesture is started, we offset the animation by the threshold. private float mShiftAtGestureStart = 0; @@ -242,6 +229,7 @@ public class WindowTransformSwipeHandler extends private final ActivityControlHelper mActivityControlHelper; private final ActivityInitListener mActivityInitListener; + private final RecentsModel mRecentsModel; private final SysUINavigationMode.Mode mMode; @@ -254,7 +242,6 @@ public class WindowTransformSwipeHandler extends private boolean mHasLauncherTransitionControllerStarted; private T mActivity; - private RecentsView mRecentsView; private AnimationFactory mAnimationFactory = (t) -> { }; private LiveTileOverlay mLiveTileOverlay = new LiveTileOverlay(); @@ -276,11 +263,12 @@ public class WindowTransformSwipeHandler extends public WindowTransformSwipeHandler(RunningTaskInfo runningTaskInfo, Context context, long touchTimeMs, ActivityControlHelper controller, boolean continuingLastGesture, - InputConsumerController inputConsumer) { + InputConsumerController inputConsumer, RecentsModel recentsModel) { super(context); mRunningTaskId = runningTaskInfo.id; mTouchTimeMs = touchTimeMs; mActivityControlHelper = controller; + mRecentsModel = recentsModel; mActivityInitListener = mActivityControlHelper .createActivityInitListener(this::onActivityInit); mContinuingLastGesture = continuingLastGesture; @@ -375,7 +363,11 @@ public class WindowTransformSwipeHandler extends } } + @Override public void initWhenReady() { + // Preload the plan + mRecentsModel.getTasks(null); + mActivityInitListener.register(); } @@ -546,15 +538,7 @@ public class WindowTransformSwipeHandler extends return TaskView.getCurveScaleForInterpolation(interpolation); } - public Consumer getRecentsViewDispatcher(RotationMode rotationMode) { - return mRecentsView != null ? mRecentsView.getEventDispatcher(rotationMode) : null; - } - - @UiThread - public void updateDisplacement(float displacement) { - mCurrentShift.updateValue(getShiftForDisplacement(displacement)); - } - + @Override public void onMotionPauseChanged(boolean isPaused) { setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION); } @@ -605,6 +589,7 @@ public class WindowTransformSwipeHandler extends mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); } + @Override public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) { mIsLikelyToStartNewTask = isLikelyToStartNewTask; @@ -651,7 +636,8 @@ public class WindowTransformSwipeHandler extends } @UiThread - private void updateFinalShift() { + @Override + public void updateFinalShift() { float shift = mCurrentShift.value; SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController(); @@ -766,7 +752,7 @@ public class WindowTransformSwipeHandler extends TOUCH_INTERACTION_LOG.addLog("cancelRecentsAnimation"); } - @UiThread + @Override public void onGestureStarted() { notifyGestureStartedAsync(); mShiftAtGestureStart = mCurrentShift.value; @@ -790,7 +776,7 @@ public class WindowTransformSwipeHandler extends /** * Called as a result on ACTION_CANCEL to return the UI to the start state. */ - @UiThread + @Override public void onGestureCancelled() { updateDisplacement(0); setStateOnUiThread(STATE_GESTURE_COMPLETED); @@ -803,7 +789,7 @@ public class WindowTransformSwipeHandler extends * @param velocity The x and y components of the velocity when the gesture ends. * @param downPos The x and y value of where the gesture started. */ - @UiThread + @Override public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { float flingThreshold = mContext.getResources() .getDimension(R.dimen.quickstep_fling_threshold_velocity); @@ -1174,11 +1160,18 @@ public class WindowTransformSwipeHandler extends return anim; } - /** - * @return The GestureEndTarget if the gesture has ended, else null. - */ - public @Nullable GestureEndTarget getGestureEndTarget() { - return mGestureEndTarget; + @Override + public void onConsumerAboutToBeSwitched(SwipeSharedState sharedState) { + if (mGestureEndTarget != null) { + sharedState.canGestureBeContinued = mGestureEndTarget.canBeContinued; + sharedState.goingToLauncher = mGestureEndTarget.isLauncher; + } + + if (sharedState.canGestureBeContinued) { + cancelCurrentAnimation(sharedState); + } else { + reset(); + } } @UiThread @@ -1227,7 +1220,7 @@ public class WindowTransformSwipeHandler extends TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", true); } - public void reset() { + private void reset() { setStateOnUiThread(STATE_HANDLER_INVALIDATED); } @@ -1235,7 +1228,7 @@ public class WindowTransformSwipeHandler extends * Cancels any running animation so that the active target can be overriden by a new swipe * handle (in case of quick switch). */ - public void cancelCurrentAnimation(SwipeSharedState sharedState) { + private void cancelCurrentAnimation(SwipeSharedState sharedState) { mCanceled = true; mCurrentShift.cancelAnimation(); if (mLauncherTransitionController != null && mLauncherTransitionController @@ -1398,10 +1391,6 @@ public class WindowTransformSwipeHandler extends reset(); } - public void setGestureEndCallback(Runnable gestureEndCallback) { - mGestureEndCallback = gestureEndCallback; - } - private void setTargetAlphaProvider(TargetAlphaProvider provider) { mClipAnimationHelper.setTaskAlphaCallback(provider); updateFinalShift(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java index cdd91b78f4..a5a8f388f4 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/FallbackNoButtonInputConsumer.java @@ -15,23 +15,12 @@ */ package com.android.quickstep.inputconsumers; -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_POINTER_DOWN; -import static android.view.MotionEvent.ACTION_POINTER_UP; -import static android.view.MotionEvent.ACTION_UP; -import static android.view.MotionEvent.INVALID_POINTER_ID; - import static com.android.quickstep.RecentsActivity.EXTRA_TASK_ID; import static com.android.quickstep.RecentsActivity.EXTRA_THUMBNAIL; import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.HOME; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.LAST_TASK; import static com.android.quickstep.inputconsumers.FallbackNoButtonInputConsumer.GestureEndTarget.RECENTS; -import static com.android.quickstep.inputconsumers.OtherActivityInputConsumer.QUICKSTEP_TOUCH_SLOP_RATIO; -import static com.android.quickstep.TouchInteractionService.startRecentsActivityAsync; -import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -42,11 +31,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.PointF; import android.graphics.Rect; -import android.graphics.RectF; import android.os.Bundle; -import android.view.MotionEvent; -import android.view.VelocityTracker; -import android.view.ViewConfiguration; import android.view.WindowManager; import com.android.launcher3.DeviceProfile; @@ -56,20 +41,12 @@ import com.android.quickstep.ActivityControlHelper; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.OverviewComponentObserver; -import com.android.quickstep.SwipeSharedState; -import com.android.quickstep.util.MotionPauseDetector; -import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.ObjectWrapper; -import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.quickstep.util.SwipeAnimationTargetSet; -import com.android.quickstep.util.SwipeAnimationTargetSet.SwipeAnimationListener; import com.android.systemui.shared.recents.model.ThumbnailData; -import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler - implements InputConsumer, SwipeAnimationListener { +public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler { public enum GestureEndTarget { HOME(3, 100, 1), @@ -79,6 +56,7 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler private final float mEndProgress; private final long mDurationMultiplier; private final float mLauncherAlpha; + GestureEndTarget(float endProgress, long durationMultiplier, float launcherAlpha) { mEndProgress = endProgress; mDurationMultiplier = durationMultiplier; @@ -87,68 +65,26 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler } private final ActivityControlHelper mActivityControlHelper; - private final InputMonitorCompat mInputMonitor; - private final NavBarPosition mNavBarPosition; - private final SwipeSharedState mSwipeSharedState; private final OverviewComponentObserver mOverviewComponentObserver; private final int mRunningTaskId; private final DeviceProfile mDP; - private final MotionPauseDetector mMotionPauseDetector; - private final float mMotionPauseMinDisplacement; private final Rect mTargetRect = new Rect(); - private final RectF mSwipeTouchRegion; - private final boolean mDisableHorizontalSwipe; - - private final PointF mDownPos = new PointF(); - private final PointF mLastPos = new PointF(); - private final AnimatedFloat mLauncherAlpha = new AnimatedFloat(this::onLauncherAlphaChanged); - private final AnimatedFloat mProgress = new AnimatedFloat(this::onProgressChanged); - private int mActivePointerId = -1; - // Slop used to determine when we say that the gesture has started. - private boolean mPassedPilferInputSlop; - - private VelocityTracker mVelocityTracker; - - // Distance after which we start dragging the window. - private final float mTouchSlop; - - // Might be displacement in X or Y, depending on the direction we are swiping from the nav bar. - private float mStartDisplacement; private SwipeAnimationTargetSet mSwipeAnimationTargetSet; private boolean mIsMotionPaused = false; private GestureEndTarget mEndTarget; public FallbackNoButtonInputConsumer(Context context, - ActivityControlHelper activityControlHelper, InputMonitorCompat inputMonitor, - SwipeSharedState swipeSharedState, RectF swipeTouchRegion, OverviewComponentObserver overviewComponentObserver, - boolean disableHorizontalSwipe, RunningTaskInfo runningTaskInfo) { + RunningTaskInfo runningTaskInfo) { super(context); - mActivityControlHelper = activityControlHelper; - mInputMonitor = inputMonitor; mOverviewComponentObserver = overviewComponentObserver; + mActivityControlHelper = overviewComponentObserver.getActivityControlHelper(); mRunningTaskId = runningTaskInfo.id; - - mMotionPauseDetector = new MotionPauseDetector(context); - mMotionPauseMinDisplacement = context.getResources().getDimension( - R.dimen.motion_pause_detector_min_displacement_from_app); - mMotionPauseDetector.setOnMotionPauseListener(this::onMotionPauseChanged); - - mSwipeSharedState = swipeSharedState; - mSwipeTouchRegion = swipeTouchRegion; - mDisableHorizontalSwipe = disableHorizontalSwipe; - - mNavBarPosition = new NavBarPosition(context); - mVelocityTracker = VelocityTracker.obtain(); - - mTouchSlop = QUICKSTEP_TOUCH_SLOP_RATIO - * ViewConfiguration.get(context).getScaledTouchSlop(); - mDP = InvariantDeviceProfile.INSTANCE.get(context).getDeviceProfile(context).copy(context); mLauncherAlpha.value = 1; @@ -156,18 +92,14 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler initTransitionTarget(); } - @Override - public int getType() { - return TYPE_FALLBACK_NO_BUTTON; - } - private void onLauncherAlphaChanged() { if (mSwipeAnimationTargetSet != null && mEndTarget == null) { mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); } } - private void onMotionPauseChanged(boolean isPaused) { + @Override + public void onMotionPauseChanged(boolean isPaused) { mIsMotionPaused = isPaused; mLauncherAlpha.animateToValue(mLauncherAlpha.value, isPaused ? 0 : 1) .setDuration(150).start(); @@ -175,150 +107,36 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler } @Override - public void onMotionEvent(MotionEvent ev) { - if (mVelocityTracker == null) { - return; - } - - mVelocityTracker.addMovement(ev); - if (ev.getActionMasked() == ACTION_POINTER_UP) { - mVelocityTracker.clear(); - mMotionPauseDetector.clear(); - } - - switch (ev.getActionMasked()) { - case ACTION_DOWN: { - mActivePointerId = ev.getPointerId(0); - mDownPos.set(ev.getX(), ev.getY()); - mLastPos.set(mDownPos); - break; - } - case ACTION_POINTER_DOWN: { - if (!mPassedPilferInputSlop) { - // Cancel interaction in case of multi-touch interaction - int ptrIdx = ev.getActionIndex(); - if (!mSwipeTouchRegion.contains(ev.getX(ptrIdx), ev.getY(ptrIdx))) { - forceCancelGesture(ev); - } - } - break; - } - case ACTION_POINTER_UP: { - int ptrIdx = ev.getActionIndex(); - int ptrId = ev.getPointerId(ptrIdx); - if (ptrId == mActivePointerId) { - final int newPointerIdx = ptrIdx == 0 ? 1 : 0; - mDownPos.set( - ev.getX(newPointerIdx) - (mLastPos.x - mDownPos.x), - ev.getY(newPointerIdx) - (mLastPos.y - mDownPos.y)); - mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx)); - mActivePointerId = ev.getPointerId(newPointerIdx); - } - break; - } - case ACTION_MOVE: { - int pointerIndex = ev.findPointerIndex(mActivePointerId); - if (pointerIndex == INVALID_POINTER_ID) { - break; - } - mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex)); - float displacement = getDisplacement(ev); - - if (!mPassedPilferInputSlop) { - if (mDisableHorizontalSwipe && Math.abs(mLastPos.x - mDownPos.x) - > Math.abs(mLastPos.y - mDownPos.y)) { - // Horizontal gesture is not allowed in this region - forceCancelGesture(ev); - break; - } - - if (Math.abs(displacement) >= mTouchSlop) { - mPassedPilferInputSlop = true; - - // Deferred gesture, start the animation and gesture tracking once - // we pass the actual touch slop - startTouchTrackingForWindowAnimation(displacement); - } - } else { - updateDisplacement(displacement - mStartDisplacement); - mMotionPauseDetector.setDisallowPause( - -displacement < mMotionPauseMinDisplacement); - mMotionPauseDetector.addPosition(displacement, ev.getEventTime()); - } - break; - } - case ACTION_CANCEL: - case ACTION_UP: { - finishTouchTracking(ev); - break; - } - } - } - - private void startTouchTrackingForWindowAnimation(float displacement) { - mStartDisplacement = Math.min(displacement, -mTouchSlop); - - RecentsAnimationListenerSet listenerSet = - mSwipeSharedState.newRecentsAnimationListenerSet(); - listenerSet.addListener(this); - Intent homeIntent = mOverviewComponentObserver.getHomeIntent(); - startRecentsActivityAsync(homeIntent, listenerSet); - - ActivityManagerWrapper.getInstance().closeSystemWindows( - CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); - mInputMonitor.pilferPointers(); - } - - private void updateDisplacement(float displacement) { - mProgress.updateValue(getShiftForDisplacement(displacement)); - } - - private void onProgressChanged() { - mTransformParams.setProgress(mProgress.value); + public void updateFinalShift() { + mTransformParams.setProgress(mCurrentShift.value); if (mSwipeAnimationTargetSet != null) { mClipAnimationHelper.applyTransform(mSwipeAnimationTargetSet, mTransformParams); } } - private void forceCancelGesture(MotionEvent ev) { - int action = ev.getAction(); - ev.setAction(ACTION_CANCEL); - finishTouchTracking(ev); - ev.setAction(action); + @Override + public void onGestureCancelled() { + updateDisplacement(0); + mEndTarget = LAST_TASK; + finishAnimationTargetSetAnimationComplete(); } - /** - * Called when the gesture has ended. Does not correlate to the completion of the interaction as - * the animation can still be running. - */ - private void finishTouchTracking(MotionEvent ev) { - if (ev.getAction() == ACTION_CANCEL) { - mEndTarget = LAST_TASK; + @Override + public void onGestureEnded(float endVelocity, PointF velocity, PointF downPos) { + float flingThreshold = mContext.getResources() + .getDimension(R.dimen.quickstep_fling_threshold_velocity); + boolean isFling = Math.abs(endVelocity) > flingThreshold; + + if (isFling) { + mEndTarget = endVelocity < 0 ? HOME : LAST_TASK; + } else if (mIsMotionPaused) { + mEndTarget = RECENTS; } else { - mVelocityTracker.computeCurrentVelocity(1000, - ViewConfiguration.get(mContext).getScaledMaximumFlingVelocity()); - float velocityX = mVelocityTracker.getXVelocity(mActivePointerId); - float velocityY = mVelocityTracker.getYVelocity(mActivePointerId); - float velocity = mNavBarPosition.isRightEdge() ? velocityX - : mNavBarPosition.isLeftEdge() ? -velocityX - : velocityY; - float flingThreshold = mContext.getResources() - .getDimension(R.dimen.quickstep_fling_threshold_velocity); - boolean isFling = Math.abs(velocity) > flingThreshold; - - if (isFling) { - mEndTarget = velocity < 0 ? HOME : LAST_TASK; - } else if (mIsMotionPaused) { - mEndTarget = RECENTS; - } else { - mEndTarget = mProgress.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; - } + mEndTarget = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW ? HOME : LAST_TASK; } - if (mSwipeAnimationTargetSet != null) { finishAnimationTargetSet(); } - mMotionPauseDetector.clear(); } private void finishAnimationTargetSetAnimationComplete() { @@ -346,19 +164,22 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler break; } } + if (mGestureEndCallback != null) { + mGestureEndCallback.run(); + } } private void finishAnimationTargetSet() { float endProgress = mEndTarget.mEndProgress; - if (mProgress.value != endProgress) { + if (mCurrentShift.value != endProgress) { AnimatorSet anim = new AnimatorSet(); anim.play(mLauncherAlpha.animateToValue( mLauncherAlpha.value, mEndTarget.mLauncherAlpha)); - anim.play(mProgress.animateToValue(mProgress.value, endProgress)); + anim.play(mCurrentShift.animateToValue(mCurrentShift.value, endProgress)); anim.setDuration((long) (mEndTarget.mDurationMultiplier * - Math.abs(endProgress - mProgress.value))); + Math.abs(endProgress - mCurrentShift.value))); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -403,19 +224,4 @@ public class FallbackNoButtonInputConsumer extends BaseSwipeUpHandler @Override public void onRecentsAnimationCanceled() { } - - private float getDisplacement(MotionEvent ev) { - if (mNavBarPosition.isRightEdge()) { - return ev.getX() - mDownPos.x; - } else if (mNavBarPosition.isLeftEdge()) { - return mDownPos.x - ev.getX(); - } else { - return ev.getY() - mDownPos.y; - } - } - - @Override - public boolean allowInterceptByParent() { - return !mPassedPilferInputSlop; - } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java index f5cf654b15..a1e5d47a53 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java @@ -33,7 +33,6 @@ public interface InputConsumer { int TYPE_SCREEN_PINNED = 1 << 6; int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7; int TYPE_RESET_GESTURE = 1 << 8; - int TYPE_FALLBACK_NO_BUTTON = 1 << 9; String[] NAMES = new String[] { "TYPE_NO_OP", // 0 @@ -45,7 +44,6 @@ public interface InputConsumer { "TYPE_SCREEN_PINNED", // 6 "TYPE_OVERVIEW_WITHOUT_FOCUS", // 7 "TYPE_RESET_GESTURE", // 8 - "TYPE_FALLBACK_NO_BUTTON", // 9 }; InputConsumer NO_OP = () -> TYPE_NO_OP; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index a4d2f39d29..9114995cc9 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -49,20 +49,16 @@ import com.android.launcher3.R; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.RaceConditionTracker; import com.android.launcher3.util.TraceHelper; -import com.android.quickstep.ActivityControlHelper; +import com.android.quickstep.BaseSwipeUpHandler; import com.android.quickstep.OverviewCallbacks; -import com.android.quickstep.RecentsModel; import com.android.quickstep.SwipeSharedState; import com.android.quickstep.SysUINavigationMode; import com.android.quickstep.SysUINavigationMode.Mode; -import com.android.quickstep.WindowTransformSwipeHandler; -import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget; import com.android.quickstep.util.CachedEventDispatcher; import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.NavBarPosition; import com.android.quickstep.util.RecentsAnimationListenerSet; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InputMonitorCompat; import java.util.function.Consumer; @@ -83,16 +79,15 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher(); private final RunningTaskInfo mRunningTask; - private final RecentsModel mRecentsModel; private final Intent mHomeIntent; - private final ActivityControlHelper mActivityControlHelper; private final OverviewCallbacks mOverviewCallbacks; - private final InputConsumerController mInputConsumer; private final SwipeSharedState mSwipeSharedState; private final InputMonitorCompat mInputMonitorCompat; private final SysUINavigationMode.Mode mMode; private final RectF mSwipeTouchRegion; + private final BaseSwipeUpHandler.Factory mHandlerFactory; + private final NavBarPosition mNavBarPosition; private final Consumer mOnCompleteCallback; @@ -100,7 +95,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final float mMotionPauseMinDisplacement; private VelocityTracker mVelocityTracker; - private WindowTransformSwipeHandler mInteractionHandler; + private BaseSwipeUpHandler mInteractionHandler; private final boolean mIsDeferredDownTarget; private final PointF mDownPos = new PointF(); @@ -114,7 +109,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final boolean mDisableHorizontalSwipe; // Slop used to check when we start moving window. - private boolean mPaddedWindowMoveSlop; + private boolean mPassedWindowMoveSlop; // Slop used to determine when we say that the gesture has started. private boolean mPassedPilferInputSlop; @@ -122,26 +117,24 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private float mStartDisplacement; private Handler mMainThreadHandler; - private Runnable mCancelRecentsAnimationRunnable = () -> { + private Runnable mCancelRecentsAnimationRunnable = () -> ActivityManagerWrapper.getInstance().cancelRecentsAnimation( true /* restoreHomeStackPosition */); - }; public OtherActivityInputConsumer(Context base, RunningTaskInfo runningTaskInfo, - RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl, - boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, - InputConsumerController inputConsumer, + Intent homeIntent, boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks, Consumer onCompleteCallback, SwipeSharedState swipeSharedState, InputMonitorCompat inputMonitorCompat, - RectF swipeTouchRegion, boolean disableHorizontalSwipe) { + RectF swipeTouchRegion, boolean disableHorizontalSwipe, + BaseSwipeUpHandler.Factory handlerFactory) { super(base); mMainThreadHandler = new Handler(Looper.getMainLooper()); mRunningTask = runningTaskInfo; - mRecentsModel = recentsModel; mHomeIntent = homeIntent; mMode = SysUINavigationMode.getMode(base); mSwipeTouchRegion = swipeTouchRegion; + mHandlerFactory = handlerFactory; mMotionPauseDetector = new MotionPauseDetector(base); mMotionPauseMinDisplacement = base.getResources().getDimension( @@ -150,11 +143,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mVelocityTracker = VelocityTracker.obtain(); mInputMonitorCompat = inputMonitorCompat; - mActivityControlHelper = activityControl; boolean continuingPreviousGesture = swipeSharedState.getActiveListener() != null; mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget; mOverviewCallbacks = overviewCallbacks; - mInputConsumer = inputConsumer; mSwipeSharedState = swipeSharedState; mNavBarPosition = new NavBarPosition(base); @@ -163,7 +154,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC float slop = QUICKSTEP_TOUCH_SLOP_RATIO * mTouchSlop; mSquaredTouchSlop = slop * slop; - mPassedPilferInputSlop = mPaddedWindowMoveSlop = continuingPreviousGesture; + mPassedPilferInputSlop = mPassedWindowMoveSlop = continuingPreviousGesture; mDisableHorizontalSwipe = !mPassedPilferInputSlop && disableHorizontalSwipe; } @@ -186,7 +177,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } // Proxy events to recents view - if (mPaddedWindowMoveSlop && mInteractionHandler != null + if (mPassedWindowMoveSlop && mInteractionHandler != null && !mRecentsViewDispatcher.hasConsumer()) { mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher( mNavBarPosition.getRotationMode())); @@ -251,12 +242,12 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC float displacement = getDisplacement(ev); float displacementX = mLastPos.x - mDownPos.x; - if (!mPaddedWindowMoveSlop) { + if (!mPassedWindowMoveSlop) { if (!mIsDeferredDownTarget) { // Normal gesture, ensure we pass the drag slop before we start tracking // the gesture if (Math.abs(displacement) > mTouchSlop) { - mPaddedWindowMoveSlop = true; + mPassedWindowMoveSlop = true; mStartDisplacement = Math.min(displacement, -mTouchSlop); } } @@ -279,8 +270,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // we pass the actual touch slop startTouchTrackingForWindowAnimation(ev.getEventTime()); } - if (!mPaddedWindowMoveSlop) { - mPaddedWindowMoveSlop = true; + if (!mPassedWindowMoveSlop) { + mPassedWindowMoveSlop = true; mStartDisplacement = Math.min(displacement, -mTouchSlop); } @@ -289,7 +280,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (mInteractionHandler != null) { - if (mPaddedWindowMoveSlop) { + if (mPassedWindowMoveSlop) { // Move mInteractionHandler.updateDisplacement(displacement - mStartDisplacement); } @@ -333,12 +324,9 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC TOUCH_INTERACTION_LOG.addLog("startRecentsAnimation"); RecentsAnimationListenerSet listenerSet = mSwipeSharedState.getActiveListener(); - final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler( - mRunningTask, this, touchTimeMs, mActivityControlHelper, - listenerSet != null, mInputConsumer); + final BaseSwipeUpHandler handler = mHandlerFactory.newHandler(mRunningTask, touchTimeMs, + listenerSet != null); - // Preload the plan - mRecentsModel.getTasks(null); mInteractionHandler = handler; handler.setGestureEndCallback(this::onInteractionGestureFinished); mMotionPauseDetector.setOnMotionPauseListener(handler::onMotionPauseChanged); @@ -364,7 +352,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC RaceConditionTracker.onEvent(UP_EVT, ENTER); TraceHelper.endSection("TouchInt"); - if (mPaddedWindowMoveSlop && mInteractionHandler != null) { + if (mPassedWindowMoveSlop && mInteractionHandler != null) { if (ev.getActionMasked() == ACTION_CANCEL) { mInteractionHandler.onGestureCancelled(); } else { @@ -407,14 +395,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // The consumer is being switched while we are active. Set up the shared state to be // used by the next animation removeListener(); - GestureEndTarget endTarget = mInteractionHandler.getGestureEndTarget(); - mSwipeSharedState.canGestureBeContinued = endTarget != null && endTarget.canBeContinued; - mSwipeSharedState.goingToLauncher = endTarget != null && endTarget.isLauncher; - if (mSwipeSharedState.canGestureBeContinued) { - mInteractionHandler.cancelCurrentAnimation(mSwipeSharedState); - } else { - mInteractionHandler.reset(); - } + mInteractionHandler.onConsumerAboutToBeSwitched(mSwipeSharedState); } }