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

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

Merge "Rotate quickswitch task thumbnails" into ub-launcher3-master

parents 68dce811 8648eee7
Loading
Loading
Loading
Loading
+69 −35
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TI
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
@@ -38,11 +37,11 @@ import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Property;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;

import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
@@ -102,7 +101,7 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
    private float mSaturation = 1f;

    private boolean mOverlayEnabled;
    private boolean mRotated;
    private boolean mIsOrientationChanged;
    private OverviewScreenshotActions mOverviewScreenshotActionsPlugin;

    public TaskThumbnailView(Context context) {
@@ -323,7 +322,7 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc

    private void updateOverlay() {
        // The overlay doesn't really work when the screenshot is rotated, so don't add it.
        if (mOverlayEnabled && !mRotated && mBitmapShader != null && mThumbnailData != null) {
        if (mOverlayEnabled && !mIsOrientationChanged && mBitmapShader != null && mThumbnailData != null) {
            mOverlay.initOverlay(mTask, mThumbnailData, mMatrix);
        } else {
            mOverlay.reset();
@@ -346,6 +345,7 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc

    private void updateThumbnailMatrix() {
        boolean isRotated = false;
        boolean isOrientationDifferent = false;
        mClipBottom = -1;
        if (mBitmapShader != null && mThumbnailData != null) {
            float scale = mThumbnailData.scale;
@@ -356,51 +356,40 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
                    (thumbnailInsets.top + thumbnailInsets.bottom) * scale;

            final float thumbnailScale;
            final DeviceProfile profile = mActivity.getDeviceProfile();

            int thumbnailRotation = mThumbnailData.rotation;
            int currentRotation = getDisplay() != null ? getDisplay().getRotation() : 0;
            int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation);
            // Landscape vs portrait change
            boolean windowingModeSupportsRotation = !mActivity.isInMultiWindowMode()
                    && mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
            isOrientationDifferent = isOrientationChange(deltaRotate)
                && windowingModeSupportsRotation;
            if (getMeasuredWidth() == 0) {
                // If we haven't measured , skip the thumbnail drawing and only draw the background
                // color
                thumbnailScale = 0f;
            } else {
                final Configuration configuration =
                        getContext().getResources().getConfiguration();
                // Rotate the screenshot if not in multi-window mode
                isRotated = configuration.orientation != mThumbnailData.orientation &&
                        !mActivity.isInMultiWindowMode() &&
                        mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
                isRotated = deltaRotate > 0 && windowingModeSupportsRotation;
                // Scale the screenshot to always fit the width of the card.
                thumbnailScale = isRotated

                thumbnailScale = isOrientationDifferent
                        ? getMeasuredWidth() / thumbnailHeight
                        : getMeasuredWidth() / thumbnailWidth;
            }

            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;
                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();
                    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);
                } else {
                    mMatrix.postTranslate(0, mThumbnailData.thumbnail.getWidth());
                }
            } else {
                mClippedInsets.offsetTo(thumbnailInsets.left * scale, thumbnailInsets.top * scale);
            if (!isRotated) {
                // No Rotation
                mClippedInsets.offsetTo(thumbnailInsets.left * scale,
                    thumbnailInsets.top * scale);
                mMatrix.setTranslate(-mClippedInsets.left, -mClippedInsets.top);
            } else {
                setThumbnailRotation(deltaRotate, thumbnailInsets, scale);
            }

            final float widthWithInsets;
            final float heightWithInsets;
            if (isRotated) {
            if (isOrientationDifferent) {
                widthWithInsets = mThumbnailData.thumbnail.getHeight() * thumbnailScale;
                heightWithInsets = mThumbnailData.thumbnail.getWidth() * thumbnailScale;
            } else {
@@ -415,7 +404,7 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
            mMatrix.postScale(thumbnailScale, thumbnailScale);
            mBitmapShader.setLocalMatrix(mMatrix);

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

        mRotated = isRotated;
        mIsOrientationChanged = isOrientationDifferent;
        invalidate();

        // Update can be called from {@link #onSizeChanged} during layout, post handling of overlay
@@ -431,6 +420,51 @@ public class TaskThumbnailView extends View implements PluginListener<OverviewSc
        post(this::updateOverlay);
    }

    private int getRotationDelta(int oldRotation, int newRotation) {
        int delta = newRotation - oldRotation;
        if (delta < 0) delta += 4;
        return delta;
    }

    /**
     * @param deltaRotation the number of 90 degree turns from the current orientation
     * @return {@code true} if the change in rotation results in a shift from landscape to portrait
     * or vice versa, {@code false} otherwise
     */
    private boolean isOrientationChange(int deltaRotation) {
        return deltaRotation == Surface.ROTATION_90 || deltaRotation == Surface.ROTATION_270;
    }

    private void setThumbnailRotation(int deltaRotate, Rect thumbnailInsets, float scale) {
        int newLeftInset = 0;
        int newTopInset = 0;
        int translateX = 0;
        int translateY = 0;

        mMatrix.setRotate(90 * deltaRotate);
        switch (deltaRotate) { /* Counter-clockwise */
            case Surface.ROTATION_90:
                newLeftInset = thumbnailInsets.bottom;
                newTopInset = thumbnailInsets.left;
                translateX = mThumbnailData.thumbnail.getHeight();
                break;
            case Surface.ROTATION_270:
                newLeftInset = thumbnailInsets.top;
                newTopInset = thumbnailInsets.right;
                translateY = mThumbnailData.thumbnail.getWidth();
                break;
            case Surface.ROTATION_180:
                newLeftInset = -thumbnailInsets.top;
                newTopInset = -thumbnailInsets.left;
                translateX = mThumbnailData.thumbnail.getWidth();
                translateY = mThumbnailData.thumbnail.getHeight();
                break;
        }
        mClippedInsets.offsetTo(newLeftInset * scale, newTopInset * scale);
        mMatrix.postTranslate(translateX - mClippedInsets.left,
                translateY - mClippedInsets.top);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);