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

Commit c857ad80 authored by Tony Wickham's avatar Tony Wickham Committed by Android (Google) Code Review
Browse files

Merge "Fix fullscreen and landscape task insets" into ub-launcher3-qt-dev

parents 5a30308d 52aada01
Loading
Loading
Loading
Loading
+2 −14
Original line number Diff line number Diff line
@@ -17,13 +17,10 @@ package com.android.launcher3.uioverrides.states;

import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;

import android.graphics.Rect;

import com.android.launcher3.Launcher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;

/**
@@ -45,18 +42,9 @@ public class QuickSwitchState extends OverviewState {
        if (recentsView.getTaskViewCount() == 0) {
            return super.getOverviewScaleAndTranslation(launcher);
        }
        // Compute scale and translation y such that the most recent task view fills the screen.
        TaskThumbnailView dummyThumbnail = recentsView.getTaskViewAt(0).getThumbnail();
        TaskView dummyTask = recentsView.getTaskViewAt(0);
        ClipAnimationHelper clipAnimationHelper = new ClipAnimationHelper(launcher);
        clipAnimationHelper.fromTaskThumbnailView(dummyThumbnail, recentsView);
        Rect targetRect = new Rect();
        recentsView.getTaskSize(targetRect);
        clipAnimationHelper.updateTargetRect(targetRect);
        float toScale = clipAnimationHelper.getSourceRect().width()
                / clipAnimationHelper.getTargetRect().width();
        float toTranslationY = clipAnimationHelper.getSourceRect().centerY()
                - clipAnimationHelper.getTargetRect().centerY();
        return new ScaleAndTranslation(toScale, 0, toTranslationY);
        return clipAnimationHelper.getOverviewFullscreenScaleAndTranslation(dummyTask);
    }

    @Override
+1 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
    @Override
    protected void updateProgress(float progress) {
        super.updateProgress(progress);
        updateFullscreenProgress(progress);
        updateFullscreenProgress(Utilities.boundToRange(progress, 0, 1));
    }

    private void updateFullscreenProgress(float progress) {
+12 −27
Original line number Diff line number Diff line
@@ -301,35 +301,20 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe
            return;
        }

        // Setup the clip animation helper source/target rects in the final transformed state
        // of the recents view (a scale/translationY may be applied prior to this animation
        // starting to line up the side pages during swipe up)
        float prevRvScale = recentsView.getScaleX();
        float prevRvTransY = recentsView.getTranslationY();
        float targetRvScale = endState.getOverviewScaleAndTranslation(launcher).scale;
        SCALE_PROPERTY.set(recentsView, targetRvScale);
        recentsView.setTranslationY(0);
        ClipAnimationHelper clipHelper = new ClipAnimationHelper(launcher);
        float tmpCurveScale = v.getCurveScale();
        v.setCurveScale(1f);
        clipHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(), null);
        v.setCurveScale(tmpCurveScale);
        SCALE_PROPERTY.set(recentsView, prevRvScale);
        recentsView.setTranslationY(prevRvTransY);

        if (!clipHelper.getSourceRect().isEmpty() && !clipHelper.getTargetRect().isEmpty()) {
            float fromScale = clipHelper.getSourceRect().width()
                    / clipHelper.getTargetRect().width();
            float fromTranslationY = clipHelper.getSourceRect().centerY()
                    - clipHelper.getTargetRect().centerY();
            Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY, fromScale, 1);
        LauncherState.ScaleAndTranslation fromScaleAndTranslation
                = clipHelper.getOverviewFullscreenScaleAndTranslation(v);
        LauncherState.ScaleAndTranslation endScaleAndTranslation
                = endState.getOverviewScaleAndTranslation(launcher);

        Animator scale = ObjectAnimator.ofFloat(recentsView, SCALE_PROPERTY,
                fromScaleAndTranslation.scale, endScaleAndTranslation.scale);
        Animator translateY = ObjectAnimator.ofFloat(recentsView, TRANSLATION_Y,
                    fromTranslationY, 0);
                fromScaleAndTranslation.translationY, endScaleAndTranslation.translationY);
        scale.setInterpolator(LINEAR);
        translateY.setInterpolator(LINEAR);
        anim.playTogether(scale, translateY);
    }
    }

    @Override
    public ActivityInitListener createActivityInitListener(
+17 −0
Original line number Diff line number Diff line
@@ -35,12 +35,14 @@ import androidx.annotation.Nullable;

import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.views.BaseDragLayer;
import com.android.quickstep.RecentsModel;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskThumbnailView;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.ISystemUiProxy;
import com.android.systemui.shared.recents.utilities.RectFEvaluator;
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
@@ -280,6 +282,21 @@ public class ClipAnimationHelper {
        }
    }

    /**
     * Compute scale and translation y such that the specified task view fills the screen.
     */
    public LauncherState.ScaleAndTranslation getOverviewFullscreenScaleAndTranslation(TaskView v) {
        TaskThumbnailView thumbnailView = v.getThumbnail();
        RecentsView recentsView = v.getRecentsView();
        fromTaskThumbnailView(thumbnailView, recentsView);
        Rect taskSize = new Rect();
        recentsView.getTaskSize(taskSize);
        updateTargetRect(taskSize);
        float scale = mSourceRect.width() / mTargetRect.width();
        float translationY = mSourceRect.centerY() - mSourceRect.top - mTargetRect.centerY();
        return new LauncherState.ScaleAndTranslation(scale, 0, translationY);
    }

    private void updateStackBoundsToMultiWindowTaskSize(BaseDraggingActivity activity) {
        ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
        if (sysUiProxy != null) {
+47 −30
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.FloatProperty;
@@ -59,7 +60,7 @@ public class TaskThumbnailView extends View {

    private final static ColorMatrix COLOR_MATRIX = new ColorMatrix();
    private final static ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
    private final static Rect EMPTY_RECT = new Rect();
    private final static RectF EMPTY_RECT_F = new RectF();

    public static final Property<TaskThumbnailView, Float> DIM_ALPHA =
            new FloatProperty<TaskThumbnailView>("dimAlpha") {
@@ -87,10 +88,9 @@ public class TaskThumbnailView extends View {
    private final Matrix mMatrix = new Matrix();

    private float mClipBottom = -1;
    private Rect mScaledInsets = new Rect();
    private Rect mCurrentDrawnInsets = new Rect();
    private float mCurrentDrawnCornerRadius;
    private boolean mIsRotated;
    // Contains the portion of the thumbnail that is clipped when fullscreen progress = 0.
    private RectF mClippedInsets = new RectF();
    private TaskView.FullscreenDrawParams mFullscreenParams;

    private Task mTask;
    private ThumbnailData mThumbnailData;
@@ -118,7 +118,7 @@ public class TaskThumbnailView extends View {
        mDimmingPaintAfterClearing.setColor(Color.BLACK);
        mActivity = BaseActivity.fromContext(context);
        mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
        setCurrentDrawnInsetsAndRadius(EMPTY_RECT, mCornerRadius);
        mFullscreenParams = new TaskView.FullscreenDrawParams(mCornerRadius);
    }

    public void bind(Task task) {
@@ -201,23 +201,27 @@ public class TaskThumbnailView extends View {

    @Override
    protected void onDraw(Canvas canvas) {
        RectF currentDrawnInsets = mFullscreenParams.mCurrentDrawnInsets;
        canvas.save();
        canvas.translate(currentDrawnInsets.left, currentDrawnInsets.top);
        canvas.scale(mFullscreenParams.mScale, mFullscreenParams.mScale);
        // Draw the insets if we're being drawn fullscreen (we do this for quick switch).
        drawOnCanvas(canvas,
                -mCurrentDrawnInsets.left,
                -mCurrentDrawnInsets.top,
                getMeasuredWidth() + mCurrentDrawnInsets.right,
                getMeasuredHeight() + mCurrentDrawnInsets.bottom,
                mCurrentDrawnCornerRadius);
                -currentDrawnInsets.left,
                -currentDrawnInsets.top,
                getMeasuredWidth() + currentDrawnInsets.right,
                getMeasuredHeight() + currentDrawnInsets.bottom,
                mFullscreenParams.mCurrentDrawnCornerRadius);
        canvas.restore();
    }

    public Rect getInsetsToDrawInFullscreen(boolean isMultiWindowMode) {
        // Don't show insets in the wrong orientation or in multi window mode.
        return mIsRotated || isMultiWindowMode ? EMPTY_RECT : mScaledInsets;
    public RectF getInsetsToDrawInFullscreen(boolean isMultiWindowMode) {
        // Don't show insets in multi window mode.
        return isMultiWindowMode ? EMPTY_RECT_F : mClippedInsets;
    }

    public void setCurrentDrawnInsetsAndRadius(Rect insets, float radius) {
        mCurrentDrawnInsets.set(insets);
        mCurrentDrawnCornerRadius = radius;
    public void setFullscreenParams(TaskView.FullscreenDrawParams fullscreenParams) {
        mFullscreenParams = fullscreenParams;
        invalidate();
    }

@@ -275,7 +279,7 @@ public class TaskThumbnailView extends View {
    }

    private void updateThumbnailMatrix() {
        mIsRotated = false;
        boolean isRotated = false;
        mClipBottom = -1;
        if (mBitmapShader != null && mThumbnailData != null) {
            float scale = mThumbnailData.scale;
@@ -296,30 +300,28 @@ public class TaskThumbnailView extends View {
                final Configuration configuration =
                        getContext().getResources().getConfiguration();
                // Rotate the screenshot if not in multi-window mode
                mIsRotated = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
                isRotated = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
                        configuration.orientation != mThumbnailData.orientation &&
                        !mActivity.isInMultiWindowMode() &&
                        mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
                // Scale the screenshot to always fit the width of the card.
                thumbnailScale = mIsRotated
                thumbnailScale = isRotated
                        ? getMeasuredWidth() / thumbnailHeight
                        : getMeasuredWidth() / thumbnailWidth;
            }

            mScaledInsets.set(thumbnailInsets);
            Utilities.scaleRect(mScaledInsets, thumbnailScale);

            if (mIsRotated) {
            if (isRotated) {
                int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1;
                mMatrix.setRotate(90 * rotationDir);
                int newLeftInset = rotationDir == 1 ? thumbnailInsets.bottom : thumbnailInsets.top;
                int newTopInset = rotationDir == 1 ? thumbnailInsets.left : thumbnailInsets.right;
                mMatrix.postTranslate(-newLeftInset * scale, -newTopInset * scale);
                mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
                if (rotationDir == -1) {
                    // Crop the right/bottom side of the screenshot rather than left/top
                    float excessHeight = thumbnailWidth * thumbnailScale - getMeasuredHeight();
                    mMatrix.postTranslate(0, -excessHeight);
                    mClippedInsets.offset(0, excessHeight);
                }
                mMatrix.postTranslate(-mClippedInsets.left, -mClippedInsets.top);
                // Move the screenshot to the thumbnail window (rotation moved it out).
                if (rotationDir == 1) {
                    mMatrix.postTranslate(mThumbnailData.thumbnail.getHeight(), 0);
@@ -327,13 +329,28 @@ public class TaskThumbnailView extends View {
                    mMatrix.postTranslate(0, mThumbnailData.thumbnail.getWidth());
                }
            } else {
                mMatrix.setTranslate(-mThumbnailData.insets.left * scale,
                        -mThumbnailData.insets.top * scale);
                mClippedInsets.offsetTo(thumbnailInsets.left * scale, thumbnailInsets.top * scale);
                mMatrix.setTranslate(-mClippedInsets.left, -mClippedInsets.top);
            }

            final float widthWithInsets;
            final float heightWithInsets;
            if (isRotated) {
                widthWithInsets = mThumbnailData.thumbnail.getHeight() * thumbnailScale;
                heightWithInsets = mThumbnailData.thumbnail.getWidth() * thumbnailScale;
            } else {
                widthWithInsets = mThumbnailData.thumbnail.getWidth() * thumbnailScale;
                heightWithInsets = mThumbnailData.thumbnail.getHeight() * thumbnailScale;
            }
            mClippedInsets.left *= thumbnailScale;
            mClippedInsets.top *= thumbnailScale;
            mClippedInsets.right = widthWithInsets - mClippedInsets.left - getMeasuredWidth();
            mClippedInsets.bottom = heightWithInsets - mClippedInsets.top - getMeasuredHeight();

            mMatrix.postScale(thumbnailScale, thumbnailScale);
            mBitmapShader.setLocalMatrix(mMatrix);

            float bitmapHeight = Math.max((mIsRotated ? thumbnailWidth : thumbnailHeight)
            float bitmapHeight = Math.max((isRotated ? thumbnailWidth : thumbnailHeight)
                    * thumbnailScale, 0);
            if (Math.round(bitmapHeight) < getMeasuredHeight()) {
                mClipBottom = bitmapHeight;
@@ -341,7 +358,7 @@ public class TaskThumbnailView extends View {
            mPaint.setShader(mBitmapShader);
        }

        if (mIsRotated) {
        if (isRotated) {
            // The overlay doesn't really work when the screenshot is rotated, so don't add it.
            mOverlay.reset();
        } else {
Loading