Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c677417d authored by Tony's avatar Tony
Browse files

Polish shelf tracking

- Offset distance based on where gesture started, so that the shelf is
  always under your finger even if you swiped up high on the nav bar
- Use the same distance when swiping down to launch a task as we use for
  swiping up from an app (so that the swipe feels more reversible)
- Allow swiping up in the gap between hotseat and overview, so there's
  no "dead zone"

Bug: 109709720
Change-Id: I828d82e8feb250fd31e382d42aeefcb11d4a07d5
parent 9e26e26f
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.TouchInteractionService;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;

@@ -97,11 +98,17 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
            }
            return false;
        }
        RecentsView recentsView = mLauncher.getOverviewPanel();
        if (mLauncher.isInState(ALL_APPS)) {
            // In all-apps only listen if the container cannot scroll itself
            if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
                return false;
            }
        } else if (mLauncher.isInState(OVERVIEW) && recentsView.getChildCount() > 0) {
            // Allow swiping up in the gap between the hotseat and overview.
            if (ev.getY() < recentsView.getChildAt(0).getBottom()) {
                return false;
            }
        } else {
            // For all other states, only listen if the event originated below the hotseat height
            DeviceProfile dp = mLauncher.getDeviceProfile();
@@ -197,7 +204,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
            // Reset the state manager, when changing the interaction mode
            mLauncher.getStateManager().goToState(OVERVIEW, false /* animate */);
            mPendingAnimation = recentsView.createTaskLauncherAnimation(taskView, maxAccuracy);
            mPendingAnimation.anim.setInterpolator(Interpolators.ZOOM_IN);
            mPendingAnimation.anim.setInterpolator(Interpolators.LINEAR);

            Runnable onCancelRunnable = () -> {
                cancelPendingAnim();
@@ -206,6 +213,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
            mCurrentAnimation = AnimatorPlaybackController.wrap(mPendingAnimation.anim, maxAccuracy,
                    onCancelRunnable);
            mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation);
            totalShift = LayoutUtils.getShelfTrackingDistance(mLauncher.getDeviceProfile());
        } else {
            mCurrentAnimation = mLauncher.getStateManager()
                    .createAnimationToNewWorkspace(mToState, builder, maxAccuracy, this::clearState,
+15 −7
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
package com.android.quickstep;

import static android.view.View.TRANSLATION_Y;

import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
@@ -38,6 +37,7 @@ import android.app.ActivityManager.RunningTaskInfo;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.os.Handler;
@@ -100,8 +100,13 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {

    void onTransitionCancelled(T activity, boolean activityVisible);

    default int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
            @InteractionType int interactionType, TransformedRect outRect) {
        return getSwipeUpDestinationAndLength(dp, context, interactionType, outRect, null);
    }

    int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
            @InteractionType int interactionType, TransformedRect outRect);
            @InteractionType int interactionType, TransformedRect outRect, PointF touchTown);

    void onSwipeUpComplete(T activity);

@@ -185,7 +190,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {

        @Override
        public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
                @InteractionType int interactionType, TransformedRect outRect) {
                @InteractionType int interactionType, TransformedRect outRect, PointF touchDown) {
            LayoutUtils.calculateLauncherTaskSize(context, dp, outRect.rect);
            if (interactionType == INTERACTION_QUICK_SCRUB) {
                outRect.scale = FastOverviewState.getOverviewScale(dp, outRect.rect, context);
@@ -195,9 +200,12 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
                int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
                return dp.hotseatBarSizePx + hotseatInset;
            } else {
                int shelfHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
                // Track slightly below the top of the shelf (between top and content).
                return shelfHeight - dp.edgeMarginPx * 2;
                int swipeLength = LayoutUtils.getShelfTrackingDistance(dp);
                if (touchDown != null) {
                    // We are already partway through based on where we touched the nav bar.
                    swipeLength -= dp.heightPx - touchDown.y;
                }
                return swipeLength;
            }
        }

@@ -456,7 +464,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {

        @Override
        public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
                @InteractionType int interactionType, TransformedRect outRect) {
                @InteractionType int interactionType, TransformedRect outRect, PointF touchDown) {
            LayoutUtils.calculateFallbackTaskSize(context, dp, outRect.rect);
            if (dp.isVerticalBarLayout()) {
                Rect targetInsets = dp.getInsets();
+1 −1
Original line number Diff line number Diff line
@@ -444,7 +444,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
            } else {
                TraceHelper.partitionSection("RecentsController", "Received");
                mInteractionHandler.onRecentsAnimationStart(mController, mTargets,
                        mHomeContentInsets, mMinimizedHomeBounds);
                        mHomeContentInsets, mMinimizedHomeBounds, mDownPos);
            }
        }
    }
+10 −6
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
@@ -175,6 +176,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
    protected boolean mIsGoingToHome;
    private DeviceProfile mDp;
    private int mTransitionDragLength;
    private PointF mTouchDown;

    // Shift in the range of [0, 1].
    // 0 => preview snapShot is completely visible, and hotseat is completely translated down
@@ -340,12 +342,12 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
        }
    }

    private void initTransitionEndpoints(DeviceProfile dp) {
    private void initTransitionEndpoints(DeviceProfile dp, PointF touchDown) {
        mDp = dp;

        TransformedRect tempRect = new TransformedRect();
        mTransitionDragLength = mActivityControlHelper
                .getSwipeUpDestinationAndLength(dp, mContext, mInteractionType, tempRect);
        mTransitionDragLength = mActivityControlHelper.getSwipeUpDestinationAndLength(
                dp, mContext, mInteractionType, tempRect, touchDown);
        mClipAnimationHelper.updateTargetRect(tempRect);
    }

@@ -569,7 +571,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
     * Called by {@link #mLayoutListener} when launcher layout changes
     */
    public void buildAnimationController() {
        initTransitionEndpoints(mActivity.getDeviceProfile());
        initTransitionEndpoints(mActivity.getDeviceProfile(), mTouchDown);
        mAnimationFactory.createActivityController(mTransitionDragLength, mInteractionType);
    }

@@ -619,7 +621,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
    }

    public void onRecentsAnimationStart(RecentsAnimationControllerCompat controller,
            RemoteAnimationTargetSet targets, Rect homeContentInsets, Rect minimizedHomeBounds) {
            RemoteAnimationTargetSet targets, Rect homeContentInsets, Rect minimizedHomeBounds,
            PointF touchDown) {
        DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(mContext).getDeviceProfile(mContext);
        final Rect overviewStackBounds;
        RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(mRunningTaskId);
@@ -650,7 +653,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
            mClipAnimationHelper.updateSource(overviewStackBounds, runningTaskTarget);
        }
        mClipAnimationHelper.prepareAnimation(false /* isOpening */);
        initTransitionEndpoints(dp);
        mTouchDown = touchDown;
        initTransitionEndpoints(dp, mTouchDown);

        mRecentsAnimationWrapper.setController(controller, targets);
        setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
+6 −0
Original line number Diff line number Diff line
@@ -111,4 +111,10 @@ public class LayoutUtils {
        outRect.set(Math.round(x), Math.round(y),
                Math.round(x + outWidth), Math.round(y + outHeight));
    }

    public static int getShelfTrackingDistance(DeviceProfile dp) {
        int shelfHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
        // Track slightly below the top of the shelf (between top and content).
        return shelfHeight - dp.edgeMarginPx * 2;
    }
}