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

Commit 3e1037d5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Added new app launch crop / positioning."

parents 877bedf6 7e40d6b2
Loading
Loading
Loading
Loading
+98 −54
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import android.graphics.drawable.Drawable;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemProperties;
import android.util.Pair;
import android.view.View;

@@ -99,6 +100,9 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans

    private static final String TAG = "QuickstepTransition";

    private static final boolean ENABLE_SHELL_STARTING_SURFACE =
            SystemProperties.getBoolean("persist.debug.shell_starting_surface", false);

    /** Duration of status bar animations. */
    public static final int STATUS_BAR_TRANSITION_DURATION = 120;

@@ -442,9 +446,9 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
            RemoteAnimationTargetCompat[] appTargets,
            RemoteAnimationTargetCompat[] wallpaperTargets,
            Rect windowTargetBounds, boolean toggleVisibility) {
        RectF bounds = new RectF();
        RectF launcherIconBounds = new RectF();
        FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v,
                toggleVisibility, bounds, true /* isOpening */);
                toggleVisibility, launcherIconBounds, true /* isOpening */);
        Rect crop = new Rect();
        Matrix matrix = new Matrix();

@@ -458,11 +462,17 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
        mDragLayer.getLocationOnScreen(dragLayerBounds);

        AnimOpenProperties prop = new AnimOpenProperties(mLauncher.getResources(), mDeviceProfile,
                windowTargetBounds, bounds, v, dragLayerBounds);
                windowTargetBounds, launcherIconBounds, v, dragLayerBounds[0], dragLayerBounds[1]);
        int left = (int) (prop.cropCenterXStart - prop.cropWidthStart / 2);
        int top = (int) (prop.cropCenterYStart - prop.cropHeightStart / 2);
        int right = (int) (left + prop.cropWidthStart);
        int bottom = (int) (top + prop.cropHeightStart);
        // Set the crop here so we can calculate the corner radius below.
        crop.set(left, top, right, bottom);

        RectF targetBounds = new RectF(windowTargetBounds);
        RectF iconBounds = new RectF();
        RectF temp = new RectF();
        RectF floatingIconBounds = new RectF();
        RectF tmpRectF = new RectF();
        Point tmpPos = new Point();

        AnimatorSet animatorSet = new AnimatorSet();
@@ -481,68 +491,79 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
        });

        final float initialWindowRadius = supportsRoundedCornersOnWindows(mLauncher.getResources())
                ? prop.startCrop / 2f : 0f;
                ? Math.max(crop.width(), crop.height()) / 2f
                : 0f;
        final float finalWindowRadius = mDeviceProfile.isMultiWindowMode
                ? 0 : getWindowCornerRadius(mLauncher.getResources());

        appAnimator.addUpdateListener(new MultiValueUpdateListener() {
            FloatProp mDx = new FloatProp(0, prop.dX, 0, prop.xDuration, AGGRESSIVE_EASE);
            FloatProp mDy = new FloatProp(0, prop.dY, 0, prop.yDuration, AGGRESSIVE_EASE);
            FloatProp mScale = new FloatProp(prop.initialAppIconScale,

            FloatProp mIconScaleToFitScreen = new FloatProp(prop.initialAppIconScale,
                    prop.finalAppIconScale, 0, APP_LAUNCH_DURATION, EXAGGERATED_EASE);
            FloatProp mIconAlpha = new FloatProp(prop.iconAlphaStart, 0f,
                    APP_LAUNCH_ALPHA_START_DELAY, prop.alphaDuration, LINEAR);
            FloatProp mCroppedSize = new FloatProp(prop.startCrop, prop.endCrop, 0, CROP_DURATION,
                    EXAGGERATED_EASE);

            FloatProp mWindowRadius = new FloatProp(initialWindowRadius, finalWindowRadius, 0,
                    RADIUS_DURATION, EXAGGERATED_EASE);
            FloatProp mShadowRadius = new FloatProp(0, mMaxShadowRadius, 0,
                    APP_LAUNCH_DURATION, EXAGGERATED_EASE);

            FloatProp mCropRectCenterX = new FloatProp(prop.cropCenterXStart, prop.cropCenterXEnd,
                    0, CROP_DURATION, EXAGGERATED_EASE);
            FloatProp mCropRectCenterY = new FloatProp(prop.cropCenterYStart, prop.cropCenterYEnd,
                    0, CROP_DURATION, EXAGGERATED_EASE);
            FloatProp mCropRectWidth = new FloatProp(prop.cropWidthStart, prop.cropWidthEnd, 0,
                    CROP_DURATION, EXAGGERATED_EASE);
            FloatProp mCropRectHeight = new FloatProp(prop.cropHeightStart, prop.cropHeightEnd, 0,
                    CROP_DURATION, EXAGGERATED_EASE);

            @Override
            public void onUpdate(float percent) {
                // Calculate the size of the scaled icon.
                float width = bounds.width() * mScale.value;
                float height = bounds.height() * mScale.value;

                // Animate the crop so that it starts off as a square.
                final int cropWidth;
                final int cropHeight;
                if (mDeviceProfile.isVerticalBarLayout()) {
                    cropWidth = (int) mCroppedSize.value;
                    cropHeight = windowTargetBounds.height();
                } else {
                    cropWidth = windowTargetBounds.width();
                    cropHeight = (int) mCroppedSize.value;
                }
                crop.set(0, 0, cropWidth, cropHeight);
                float iconWidth = launcherIconBounds.width() * mIconScaleToFitScreen.value;
                float iconHeight = launcherIconBounds.height() * mIconScaleToFitScreen.value;

                int left = (int) (mCropRectCenterX.value - mCropRectWidth.value / 2);
                int top = (int) (mCropRectCenterY.value - mCropRectHeight.value / 2);
                int right = (int) (left + mCropRectWidth.value);
                int bottom = (int) (top + mCropRectHeight.value);
                crop.set(left, top, right, bottom);

                final int windowCropWidth = crop.width();
                final int windowCropHeight = crop.height();

                // Scale the size of the icon to match the size of the window crop.
                float scaleX = width / cropWidth;
                float scaleY = height / cropHeight;
                float scaleX = iconWidth / windowCropWidth;
                float scaleY = iconHeight / windowCropHeight;
                float scale = Math.min(1f, Math.max(scaleX, scaleY));

                float scaledCropWidth = cropWidth * scale;
                float scaledCropHeight = cropHeight * scale;
                float offsetX  = (scaledCropWidth - width) / 2;
                float offsetY = (scaledCropHeight - height) / 2;
                float scaledCropWidth = windowCropWidth * scale;
                float scaledCropHeight = windowCropHeight * scale;
                float offsetX  = (scaledCropWidth - iconWidth) / 2;
                float offsetY = (scaledCropHeight - iconHeight) / 2;

                // Calculate the window position to match the icon position.
                temp.set(bounds);
                temp.offset(dragLayerBounds[0], dragLayerBounds[1]);
                temp.offset(mDx.value, mDy.value);
                Utilities.scaleRectFAboutCenter(temp, mScale.value);
                float windowTransX0 = temp.left - offsetX;
                float windowTransY0 = temp.top - offsetY;
                tmpRectF.set(launcherIconBounds);
                tmpRectF.offset(dragLayerBounds[0], dragLayerBounds[1]);
                tmpRectF.offset(mDx.value, mDy.value);
                Utilities.scaleRectFAboutCenter(tmpRectF, mIconScaleToFitScreen.value);
                float windowTransX0 = tmpRectF.left - offsetX;
                float windowTransY0 = tmpRectF.top - offsetY;
                if (ENABLE_SHELL_STARTING_SURFACE) {
                    windowTransX0 -= crop.left * scale;
                    windowTransY0 -= crop.top * scale;
                }

                // Calculate the icon position.
                iconBounds.set(bounds);
                iconBounds.offset(mDx.value, mDy.value);
                Utilities.scaleRectFAboutCenter(iconBounds, mScale.value);
                iconBounds.left -= offsetX;
                iconBounds.top -= offsetY;
                iconBounds.right += offsetX;
                iconBounds.bottom += offsetY;
                floatingIconBounds.set(launcherIconBounds);
                floatingIconBounds.offset(mDx.value, mDy.value);
                Utilities.scaleRectFAboutCenter(floatingIconBounds, mIconScaleToFitScreen.value);
                floatingIconBounds.left -= offsetX;
                floatingIconBounds.top -= offsetY;
                floatingIconBounds.right += offsetX;
                floatingIconBounds.bottom += offsetY;

                SurfaceParams[] params = new SurfaceParams[appTargets.length];
                for (int i = appTargets.length - 1; i >= 0; i--) {
@@ -553,7 +574,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
                        matrix.setScale(scale, scale);
                        matrix.postTranslate(windowTransX0, windowTransY0);

                        floatingView.update(iconBounds, mIconAlpha.value, percent, 0f,
                        floatingView.update(floatingIconBounds, mIconAlpha.value, percent, 0f,
                                mWindowRadius.value * scale, true /* isOpening */);
                        builder.withMatrix(matrix)
                                .withWindowCrop(crop)
@@ -932,8 +953,15 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
     */
    static class AnimOpenProperties {

        public final float startCrop;
        public final float endCrop;
        public final int cropCenterXStart;
        public final int cropCenterYStart;
        public final int cropWidthStart;
        public final int cropHeightStart;

        public final int cropCenterXEnd;
        public final int cropCenterYEnd;
        public final int cropWidthEnd;
        public final int cropHeightEnd;

        public final float dX;
        public final float dY;
@@ -948,7 +976,7 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
        public final float iconAlphaStart;

        AnimOpenProperties(Resources r, DeviceProfile dp, Rect windowTargetBounds,
                RectF launcherIconBounds, View view, int[] dragLayerBounds) {
                RectF launcherIconBounds, View view, int dragLayerLeft, int dragLayerTop) {
            // Scale the app icon to take up the entire screen. This simplifies the math when
            // animating the app window position / scale.
            float smallestSize = Math.min(windowTargetBounds.height(), windowTargetBounds.width());
@@ -966,8 +994,8 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
            finalAppIconScale = Math.max(maxScaleX, maxScaleY);

            // Animate the app icon to the center of the window bounds in screen coordinates.
            float centerX = windowTargetBounds.centerX() - dragLayerBounds[0];
            float centerY = windowTargetBounds.centerY() - dragLayerBounds[1];
            float centerX = windowTargetBounds.centerX() - dragLayerLeft;
            float centerY = windowTargetBounds.centerY() - dragLayerTop;

            dX = centerX - launcherIconBounds.centerX();
            dY = centerY - launcherIconBounds.centerY();
@@ -981,15 +1009,31 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
            alphaDuration = useUpwardAnimation ? APP_LAUNCH_ALPHA_DURATION
                    : APP_LAUNCH_ALPHA_DOWN_DURATION;

            if (dp.isVerticalBarLayout()) {
                startCrop = windowTargetBounds.height();
                endCrop = windowTargetBounds.width();
            if (ENABLE_SHELL_STARTING_SURFACE) {
                iconAlphaStart = 0;

                // TOOD: Share value from shell when available.
                final float windowIconSize = Utilities.pxFromSp(108, r.getDisplayMetrics());

                cropCenterXStart = windowTargetBounds.centerX();
                cropCenterYStart = windowTargetBounds.centerY();

                cropWidthStart = (int) windowIconSize;
                cropHeightStart = (int) windowIconSize;
            } else {
                startCrop = windowTargetBounds.width();
                endCrop = windowTargetBounds.height();
                iconAlphaStart = 1;

                cropWidthStart = cropHeightStart =
                        Math.min(windowTargetBounds.width(), windowTargetBounds.height());
                cropCenterXStart = cropCenterYStart =
                        Math.min(windowTargetBounds.centerX(), windowTargetBounds.centerY());
            }

            iconAlphaStart = 1f;
            cropWidthEnd = windowTargetBounds.width();
            cropHeightEnd = windowTargetBounds.height();

            cropCenterXEnd = windowTargetBounds.centerX();
            cropCenterYEnd = windowTargetBounds.centerY();
        }
    }
}