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

Commit 18c53ac2 authored by Jon Miranda's avatar Jon Miranda
Browse files

Tune springs when app animates home into the hotseat on devices

with a taskbar.

Thought about using the Builder pattern here but the CL becomes
much larger due to SwipePipToHomeAnimator having its own
Builder.

Bug: 268026344
Test: swipe up to close app thats in hotseat
      swipe back to close app thats in hotseat

Change-Id: Idd0729224374579753fc91c7820f3b04a7d3e1a4
parent 5b014860
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -136,6 +136,8 @@ import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskViewUtils;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.RectFSpringAnim.DefaultSpringConfig;
import com.android.quickstep.util.RectFSpringAnim.TaskbarHotseatSpringConfig;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.StaggeredWorkspaceAnim;
import com.android.quickstep.util.SurfaceTransaction;
@@ -1342,6 +1344,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
        }

        // Get floating view and target rect.
        boolean isInHotseat = false;
        if (launcherView instanceof LauncherAppWidgetHostView) {
            Size windowSize = new Size(mDeviceProfile.availableWidthPx,
                    mDeviceProfile.availableHeightPx);
@@ -1357,12 +1360,17 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
                            ? null
                            : mLauncher.getTaskbarUIController().findMatchingView(launcherView),
                    true /* hideOriginal */, targetRect, false /* isOpening */);
            isInHotseat = launcherView.getTag() instanceof ItemInfo
                    && ((ItemInfo) launcherView.getTag()).isInHotseat();
        } else {
            targetRect.set(getDefaultWindowTargetRect());
        }

        RectFSpringAnim anim = new RectFSpringAnim(closingWindowStartRect, targetRect, mLauncher,
                mDeviceProfile);
        boolean useTaskbarHotseatParams = mDeviceProfile.isTaskbarPresent && isInHotseat;
        RectFSpringAnim anim = new RectFSpringAnim(useTaskbarHotseatParams
                ? new TaskbarHotseatSpringConfig(mLauncher, closingWindowStartRect, targetRect)
                : new DefaultSpringConfig(mLauncher, mDeviceProfile, closingWindowStartRect,
                        targetRect));

        // Hook up floating views to the closing window animators.
        final int rotationChange = getRotationChange(targets);
+7 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import androidx.annotation.Nullable;

import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.ObjectWrapper;
@@ -122,6 +123,12 @@ public class LauncherSwipeHandlerV2 extends
                return workspaceView;
            }

            @Override
            public boolean isInHotseat() {
                return workspaceView.getTag() instanceof ItemInfo
                        && ((ItemInfo) workspaceView.getTag()).isInHotseat();
            }

            @NonNull
            @Override
            public RectF getWindowTargetRect() {
+14 −1
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.RectFSpringAnim.DefaultSpringConfig;
import com.android.quickstep.util.RectFSpringAnim.TaskbarHotseatSpringConfig;
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
@@ -157,6 +159,13 @@ public abstract class SwipeUpAnimationLogic implements
    protected abstract class HomeAnimationFactory {
        protected float mSwipeVelocity;

        /**
         * Returns true if we know the home animation involves an item in the hotseat.
         */
        public boolean isInHotseat() {
            return false;
        }

        public @NonNull RectF getWindowTargetRect() {
            PagedOrientationHandler orientationHandler = getOrientationHandler();
            DeviceProfile dp = mDp;
@@ -288,7 +297,11 @@ public abstract class SwipeUpAnimationLogic implements
        homeToWindowPositionMap.invert(windowToHomePositionMap);
        windowToHomePositionMap.mapRect(startRect);

        RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext, mDp);
        boolean useTaskbarHotseatParams = mDp.isTaskbarPresent
                && homeAnimationFactory.isInHotseat();
        RectFSpringAnim anim = new RectFSpringAnim(useTaskbarHotseatParams
                ? new TaskbarHotseatSpringConfig(mContext, startRect, targetRect)
                : new DefaultSpringConfig(mContext, mDp, startRect, targetRect));
        homeAnimationFactory.setAnimation(anim);

        SpringAnimationRunner runner = new SpringAnimationRunner(
+114 −29
Original line number Diff line number Diff line
@@ -128,37 +128,27 @@ public class RectFSpringAnim extends ReleaseCheck {

    @Tracking
    public final int mTracking;

    public RectFSpringAnim(RectF startRect, RectF targetRect, Context context,
            @Nullable DeviceProfile deviceProfile) {
        mStartRect = startRect;
        mTargetRect = targetRect;
    protected final float mStiffnessX;
    protected final float mStiffnessY;
    protected final float mDampingX;
    protected final float mDampingY;
    protected final float mRectStiffness;

    public RectFSpringAnim(SpringConfig config) {
        mStartRect = config.startRect;
        mTargetRect = config.targetRect;
        mCurrentCenterX = mStartRect.centerX();

        ResourceProvider rp = DynamicResource.provider(context);
        mMinVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
        mMaxVelocityPxPerS = (int) rp.getDimension(R.dimen.swipe_up_max_velocity);
        mMinVisChange = config.minVisChange;
        mMaxVelocityPxPerS = config.maxVelocityPxPerS;
        setCanRelease(true);

        if (deviceProfile == null) {
            mTracking = startRect.bottom < targetRect.bottom
                    ? TRACKING_BOTTOM
                    : TRACKING_TOP;
        } else {
            int heightPx = deviceProfile.heightPx;
            Rect padding = deviceProfile.workspacePadding;

            final float topThreshold = heightPx / 3f;
            final float bottomThreshold = deviceProfile.heightPx - padding.bottom;

            if (targetRect.bottom > bottomThreshold) {
                mTracking = TRACKING_BOTTOM;
            } else if (targetRect.top < topThreshold) {
                mTracking = TRACKING_TOP;
            } else {
                mTracking = TRACKING_CENTER;
            }
        }
        mTracking = config.tracking;
        mStiffnessX = config.stiffnessX;
        mStiffnessY = config.stiffnessY;
        mDampingX = config.dampingX;
        mDampingY = config.dampingY;
        mRectStiffness = config.rectStiffness;

        mCurrentY = getTrackedYFromRect(mStartRect);
    }
@@ -240,14 +230,15 @@ public class RectFSpringAnim extends ReleaseCheck {
        float maxXValue = Math.max(startX, endX);

        mRectXAnim = new FlingSpringAnim(this, context, RECT_CENTER_X, startX, endX,
                dampedXVelocityPxPerS, mMinVisChange, minXValue, maxXValue, onXEndListener);
                dampedXVelocityPxPerS, mMinVisChange, minXValue, maxXValue, mDampingX, mStiffnessX,
                onXEndListener);

        float startY = mCurrentY;
        float endY = getTrackedYFromRect(mTargetRect);
        float minYValue = Math.min(startY, endY);
        float maxYValue = Math.max(startY, endY);
        mRectYAnim = new FlingSpringAnim(this, context, RECT_Y, startY, endY, dampedYVelocityPxPerS,
                mMinVisChange, minYValue, maxYValue, onYEndListener);
                mMinVisChange, minYValue, maxYValue, mDampingY, mStiffnessY, onYEndListener);

        float minVisibleChange = Math.abs(1f / mStartRect.height());
        ResourceProvider rp = DynamicResource.provider(context);
@@ -368,4 +359,98 @@ public class RectFSpringAnim extends ReleaseCheck {

        default void onCancel() { }
    }

    private abstract static class SpringConfig {
        protected RectF startRect;
        protected RectF targetRect;
        protected @Tracking int tracking;
        protected float stiffnessX;
        protected float stiffnessY;
        protected float dampingX;
        protected float dampingY;
        protected float rectStiffness;
        protected float minVisChange;
        protected int maxVelocityPxPerS;

        private SpringConfig(Context context, RectF start, RectF target) {
            startRect = start;
            targetRect = target;

            ResourceProvider rp = DynamicResource.provider(context);
            minVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
            maxVelocityPxPerS = (int) rp.getDimension(R.dimen.swipe_up_max_velocity);
        }
    }

    /**
     * Standard spring configuration parameters.
     */
    public static class DefaultSpringConfig extends SpringConfig {

        public DefaultSpringConfig(Context context, DeviceProfile deviceProfile,
                RectF startRect, RectF targetRect) {
            super(context, startRect, targetRect);

            ResourceProvider rp = DynamicResource.provider(context);
            tracking = getDefaultTracking(deviceProfile);
            stiffnessX = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
            stiffnessY = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
            dampingX = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
            dampingY = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);

            this.startRect = startRect;
            this.targetRect = targetRect;

            // Increase the stiffness for devices where we want the window size to transform
            // quicker.
            boolean shouldUseHigherStiffness = deviceProfile != null
                    && (deviceProfile.isLandscape || deviceProfile.isTablet);
            rectStiffness = shouldUseHigherStiffness
                    ? rp.getFloat(R.dimen.swipe_up_rect_scale_higher_stiffness)
                    : rp.getFloat(R.dimen.swipe_up_rect_scale_stiffness);
        }

        private @Tracking int getDefaultTracking(@Nullable DeviceProfile deviceProfile) {
            @Tracking int tracking;
            if (deviceProfile == null) {
                tracking = startRect.bottom < targetRect.bottom
                        ? TRACKING_BOTTOM
                        : TRACKING_TOP;
            } else {
                int heightPx = deviceProfile.heightPx;
                Rect padding = deviceProfile.workspacePadding;

                final float topThreshold = heightPx / 3f;
                final float bottomThreshold = deviceProfile.heightPx - padding.bottom;

                if (targetRect.bottom > bottomThreshold) {
                    tracking = TRACKING_BOTTOM;
                } else if (targetRect.top < topThreshold) {
                    tracking = TRACKING_TOP;
                } else {
                    tracking = TRACKING_CENTER;
                }
            }
            return tracking;
        }
    }

    /**
     * Spring configuration parameters for Taskbar/Hotseat items on devices that have a taskbar.
     */
    public static class TaskbarHotseatSpringConfig extends SpringConfig {

        public TaskbarHotseatSpringConfig(Context context, RectF start, RectF target) {
            super(context, start, target);

            ResourceProvider rp = DynamicResource.provider(context);
            tracking = TRACKING_CENTER;
            stiffnessX = rp.getFloat(R.dimen.taskbar_swipe_up_rect_x_stiffness);
            stiffnessY = rp.getFloat(R.dimen.taskbar_swipe_up_rect_y_stiffness);
            dampingX = rp.getFloat(R.dimen.taskbar_swipe_up_rect_x_damping);
            dampingY = rp.getFloat(R.dimen.taskbar_swipe_up_rect_y_damping);
            rectStiffness = rp.getFloat(R.dimen.taskbar_swipe_up_rect_scale_stiffness);
        }
    }

}
+2 −1
Original line number Diff line number Diff line
@@ -124,7 +124,8 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
            int cornerRadius,
            int shadowRadius,
            @NonNull View view) {
        super(startBounds, new RectF(destinationBoundsTransformed), context, null);
        super(new DefaultSpringConfig(context, null, startBounds,
                new RectF(destinationBoundsTransformed)));
        mTaskId = taskId;
        mActivityInfo = activityInfo;
        mLeash = leash;
Loading